Hibernate:em.getReference()。getList()。add(record)performance?

时间:2013-02-14 10:39:44

标签: performance hibernate jpa

使用Hibernate(JPA)时,如果我执行以下调用:

MyParent parent = em.getReference("myId");
parent.getAListMappedAsOneToMany().add(record) 
record.setParent(parent);

有任何性能问题吗?

我的想法是getReference没有加载实体,getAListeMappedAsOneToMany().add不需要加载列表,因为它被定义为懒惰提取。

getAListMappedAsOneToMany可以返回一个非常大的列表(如果它真的被访问过(通过调用getsize方法)。

您能否确认此类代码没有性能问题?

2 个答案:

答案 0 :(得分:2)

getReference()不会转到数据库,并返回代理。但是如果在代理上调用方法,它会初始化代理并从数据库中获取实体数据。因此,当您在实体上致电getAListMappedAsOneToMany()时,通过调用getReference()代替find(),您无法获得任何收益。

同样,列表是懒惰加载的。这意味着它只会在您调用方法时加载。你确实在其上调用了一个方法:add()。因此,列表中元素的数据也会从数据库中加载。

在开发中启用SQL日志记录,以查看和理解Hibernate执行的所有查询。

如果您想避免加载列表,请用

替换您的代码
MyParent parent = em.getReference("myId");
record.setParent(parent);

这不会从数据库中加载任何内容,并且会使关联持久化,因为Record.parent是关联的所有者方。但请注意,如果之前已加载父对象,这也将使您的内存中对象图不一致。

答案 1 :(得分:1)

当您不想使用对象的任何成员但将对象的引用提供给另一个对象时,

getReference()非常有用。例如,当实体A引用实体B并且您想将b设置为A的B时,则getReference()就是您所需要的。

但在您的情况下,当您获得代理对象时,您会立即尝试联系其中一个成员。 (aListMappedAsOneToMany)因此,这将导致整个parent对象将从db加载。

确实,当您getAListMappedAsOneToMany().add(record)时,只有在设置inverse="true"

时才会从数据库加载

您可以从以下网址了解有关效果的更多信息: http://docs.jboss.org/hibernate/orm/3.3/reference/en/html/performance.html#performance-collections-mostefficentinverse