【问题标题】:Hibernate Projections List休眠投影列表
【发布时间】:2012-06-15 19:42:41
【问题描述】:

我只需要从表中获取几个列值。所以我使用 Projections 来实现这一点。该代码有效,但我认为它无效。

我的问题是当我使用 ProjectionsList 然后将 criteria.list 设置为 ArrayList - Bulletin 对象为空。我不确定如何更好地解释这一点。所以我会放代码然后请阅读以下内容:

 List<Bulletin> list = new ArrayList<Bulletin>();
 BulletinList bulletinList = null;

 Criteria criteria = null;

 criteria = this.getSession().createCriteria(Bulletin.class)
            .setProjection(Projections.projectionList()
            .add(Projections.property(bulletinIdAttr))
            .add(Projections.property(docNameAttr))   
            .add(Projections.property(docTypeCodeAttr))
            );        
    criteria.addOrder(Order.desc(createdTimeAttr));

    List<Object> rows = criteria.list();
    for (Object r : rows) {
        Object[] row = (Object[]) r;
        Bulletin bull = new Bulletin();
        bull.setBulletinId((Long) row[0]);
        bull.setDocumentName((String) row[1]);
        bull.setDocumentTypeCode((String) row[2]);
        list.add(bull);
      }

    bulletinList = new BulletinList();
    bulletinList.setBulletins(list);

    return bulletinList;

我只需要将 criteria.list 设置为 BulletinList(包含 Bulletin 对象列表的类)。但是当我使用投影时,Bulletin 对象为空。

我也在阅读另一个线程来使用

setResultTransformer(Transformers.aliasToBean

但这也行不通。那么有人可以帮助解决如何使代码变得更好。

谢谢

哈里什

【问题讨论】:

    标签: hibernate criteria projection


    【解决方案1】:

    你可以使用

     criteria = this.getSession().createCriteria(Bulletin.class)
                .setProjection(Projections.projectionList()
                .add(Projections.property(bulletinIdAttr),"bulletinIdAttr")
                .add(Projections.property(docNameAttr),"docNameAttr")   
                .add(Projections.property(docTypeCodeAttr),"docTypeCodeAttr")
                );        
    criteria.addOrder(Order.desc(createdTimeAttr));
    criteria.setResultTransformer(new AliasToBeanResultTransformer(Bulletin.class));
    List<Bulletin> bulletinList = criteria.list();
    

    这里的 criteria.setResultTransformer(new AliasToBeanResultTransformer(Bulletin.class)) 会将您的结果转换为所需的 POJO 类,但请确保您的 POJO 类(在您的情况下为 Bulletin.class)应该具有适当的设置器来设置属性值。

    现在 criteria.list() 将返回 Bulletin POJO 类的列表而不是 Object。

    【讨论】:

    • 不再参与该项目。但是非常感谢您的努力,尽管这是一个旧线程。
    • 这个问题困扰了我很多天,我无法使用 Projections.projectionList() 获取所有属性详细信息,但现在我使用这种方式执行了我的项目,非常感谢 @Shiva Agrawal 先生
    【解决方案2】:
    1. Projections.property() 将字符串作为参数。在您提供的代码中,该字符串的值应该是 Bulletin 类成员的名称。例如,大概bulletinIdAttr 是一个具有此类值的字符串,否则您将收到运行时错误。
    2. 当您在 Criteria 实例上调用 setProjection 时,您将 ResultTransformer 隐式设置为 PROJECTIONS,这就是您想要的。无需自己致电setResultTransformer。我会像这样简化例程

      List<Object[]> rows = criteria.list();
      for (Object[] row : rows) {
         Bulletin bull = new Bulletin();
         bull.setBulletinId((Long) row[0]);
         bull.setDocumentName((String) row[1]);
         bull.setDocumentTypeCode((String) row[2]);
         list.add(bull);
      }
      

    但这不应该对您的结果产生任何影响。你检查过rows 是空的吗?

    【讨论】:

    • 非常感谢您的回复。正如我所说,我上面的代码按预期工作,但只是想知道它是否有效。是的,Projections.property() 将 String 作为参数。当我尝试使用您的代码块时,出现此错误:
    • 类型不匹配:无法在线将元素类型 Object 转换为 Object[] for (Object[] row : rows)。我在这里想念什么?请告知。
    • 抱歉,Harish,我的原始答案格式不正确,导致行的声明错误。它现在应该可以工作了。
    • 这很好用。非常感谢。但是你能告诉我差异吗?使用 List vs List 以及为什么这样更好。
    • 编译后可能没有太大区别。但是当您转换结果集一次而不是两次时,代码会更清晰。 (一次作为对象,然后每行一次作为对象[])。
    【解决方案3】:

    如果您想从相同的条件进行第二次搜索,您必须更改或删除投影。例如,如果您先搜索计数:

    criteria.setProjection(Projections.rowCount());
    Integer count = criteria.list().get(0);
    

    然后想要获取所有对象:

    criteria.setProjection(null);
    List<Object> returnedObjects = criteria.list();
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-04-11
      • 2013-05-31
      • 2015-07-17
      • 2012-11-26
      • 1970-01-01
      • 1970-01-01
      • 2011-10-12
      • 1970-01-01
      相关资源
      最近更新 更多