有效地确定通过OneToMany关系引用的实体的ID

时间:2011-11-15 14:56:25

标签: java hibernate

假设我有一个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(而不是完整的对象)实际上会产生性能上的好处。

4 个答案:

答案 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节。

http://docs.jboss.org/hibernate/annotations/3.5/reference/en/html/entity.html#entity-mapping-property

将列声明为延迟初始化:

@Basic(fetch = FetchType.LAZY)    private String getYourProperty(){    }

您还需要为实体类和字节设备禁用代理。这里有一个例子:

Making a OneToOne-relation lazy

答案 3 :(得分:0)

您可以使用documentation中所述的 HQL 来建立此功能。

session.createQuery(select new OtherEntity(oe.id) OtherEntity oe 
           where oe.parentSomeEntity.someId = :someId).list();//also set someId.

OtherEntity中添加构造函数以设置idSomeEntity中应该有OtherEntity的映射。

这个HQL会在bean中设置List<OtherEntity>只有id