假设我有一个Hibernate实体,它声明与另一个实体的OneToMany
关系:
@Entity
public class SomeEntity {
@OneToMany(fetch = FetchType.LAZY)
private List<OtherEntity> otherEntities = new LinkedList<OtherEntity>();
[...]
}
将SomeEntity
映射到相应的DTO时,我需要的是将OtherEntity
标识为主键的ID(即,我实际上并不感兴趣OtherEntity
个实例)。
Hibernate是否支持这种模式,即只检索通过OneToMany
关系引用的实体的ID?
我无法影响如何检索SomeEntity
(即,我在当前Hibernate会话的范围内检索到现有的SomeEntity
实例),但我们假设尚未进行延迟加载,所以只检索子对象的ID(而不是完整的对象)实际上会产生性能上的好处。
答案 0 :(得分:1)
好吧,如果你只需要实体的ID并且你想要经济实惠,当你从数据库中获取这些实体时,你应该在查询中说明你只想获得每个条目的id,使用投影,像:
SELECT Entity.id as entity FROM Entity WHERE ...
这将返回与Entity的id字段类型相同类型的对象数组。
答案 1 :(得分:0)
您可以尝试获取主键而无需访问实体本身(没有otherEntities.get(0).getId()
)。为此,您可以使用PersistenceUnitUtil
类:
PersistenceUnitUtil#getIdentifier(yourEntity)
可以从PersistenceUnitUtil
获取EntityManagerFactory
。所以它可能是这样的:
EntityManager em = ...
PersistenceUnitUtil = em.getEntityManagerFactory().getPersistenceUnitUtil();
不幸的是,我不知道这是否会阻止实体加载的发生。但是,只访问otherEntities
集合甚至获取对每个实体的引用都不会使实例加载;你需要在获取的实体上调用一个方法,以确保它将被加载。
您还可以考虑创建@NamedQuery
并仅返回OtherEntity
ID。
HTH!
答案 2 :(得分:0)
来自hibernate参考,第2.2.2.1节。
将列声明为延迟初始化:
@Basic(fetch = FetchType.LAZY) private String getYourProperty(){ }
您还需要为实体类和字节设备禁用代理。这里有一个例子:
答案 3 :(得分:0)
您可以使用documentation中所述的 HQL 来建立此功能。
session.createQuery(select new OtherEntity(oe.id) OtherEntity oe
where oe.parentSomeEntity.someId = :someId).list();//also set someId.
在OtherEntity
中添加构造函数以设置id
,SomeEntity
中应该有OtherEntity
的映射。
这个HQL会在bean中设置List<OtherEntity>
只有id
。