1

这是一个非常简化的示例,说明了我尝试使用 Hibernate 和投影来完成的工作。以下是一些示例表:

class User{
    int id;
    String firstName;
    String lastName;
    List<Address> address ;
}

class Address{
    int id;
    String city;
    String state;   
    User user;
}

这就是我定期选择数据的方式。

Criteria crit = getSession().createCriteria("User");
crit.add(CriterionUtils.in("id", new Object[]{1,2,3}));   
criteria.list();

这有效并返回完整的用户对象和完整的地址列表。这将加载带有地址对象列表的完整用户对象。

现在我很难理解 Projections 如何与 Hibernate 一起工作。这是我的目标。我有必须加载的大型实体,但我不需要所有数据,我只需要加载几列和一个子集合,我不需要所有其他数据。本质上,我想用有限的数据加载同一个对象。但是,我不想要 User 对象的 firstName 和 lastName 因为我不需要它们;我想要一个“更轻”的用户对象,它加载了完整的地址列表和用户的 id。请记住,我的目标不是加载地址列表,而是加载具有地址列表的用户对象

如果我试试这个:

ProjectionList proList = Projections.projectionList();
proList.add(Projections.property("id"));
criteria = criteria.setProjection(proList);      
criteria.list(); //an Object[] of just the ids

我只得到 id 而没有 User 对象!

如果我试试这个:

ProjectionList proList = Projections.projectionList();
proList.add(Projections.property("id"));
proList.add(Projections.property("address"));
criteria = criteria.setProjection(proList);      
criteria.list(); //this actually fails with an Array out of bounds exception

这只是失败!

Projections 似乎只返回您想要的确切数据,而不是实体。我期待用户对象返回部分填充的字段。

也许我做错了?

4

1 回答 1

0

你做错了,我猜。不确定您真正想要达到什么,但听起来您需要在映射中进行一些延迟/代理加载,而不是投影。

lazy ="true"将加载规则设置为属性或lazy="proxy"集合的不必要列。然后,在您尝试在代码中使用它们之前,它们不会从数据库中加载。

还要记住检查 fetch 方法fetch="select"

如果你需要那个投影,你应该从地址开始,因为你的查询中有一些连接。我的建议是 - 先尝试用 SQL 编写查询,而不是把它放在 Hibernate 的 Cirteria api 中(至少在你了解它的工作原理以及如何正确使用它之前)。

于 2012-10-31T13:34:43.833 回答