0

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

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

有性能问题吗?

我的想法是getReference不加载实体,getAListeMappedAsOneToMany().add也不需要加载列表,因为它被定义为延迟获取。

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

您能否确认这样的代码没有性能问题?

4

2 回答 2

2

getReference()不去数据库,并返回一个代理。但是如果你在代理上调用一个方法,它会初始化代理并从数据库中获取实体数据。因此,由于您调用getAListMappedAsOneToMany()您的实体,因此调用getReference()而不是find().

同样,列表是延迟加载的。这意味着它只会在您调用它的方法时加载。你确实调用了一个方法:add(). 所以列表中元素的数据也是从数据库中加载的。

在 devlopment 中打开 SQL 日志记录,以查看和了解 Hibernate 执行的所有查询。

如果您想避免加载列表,请将您的代码替换为

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

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

于 2013-02-14T11:12:30.800 回答
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

于 2013-02-14T11:21:23.300 回答