考虑“Java Persistence with Hibernate”中的数据模型,其中Bid
与Item
具有惰性关联:
@ManyToOne(optional = false, fetch = FetchType.LAZY) // NOT NULL
@JoinColumn(name = "ITEM_ID") // Actually the default name
protected Item item;
然后是以下代码段尝试通过Bid
加载StatelessSession
,然后访问关联的Item
:
Bid bid = (Bid) statelessSession.get(Bid.class, bidId);
assertNotNull(bid.getItem());
assertEquals(bid.getItem().getName(), "Bike");
即使会话仍处于活动状态,也会抛出LazyInitializationException
。 我们可以从这里推断,与StatelessSession
一起不支持延迟加载吗?
org.hibernate.LazyInitializationException: could not initialize proxy - the owning Session is disconnected
at org.hibernate.proxy.AbstractLazyInitializer.initialize(AbstractLazyInitializer.java:154)
at org.hibernate.proxy.AbstractLazyInitializer.getImplementation(AbstractLazyInitializer.java:266)
at org.hibernate.proxy.pojo.javassist.JavassistLazyInitializer.invoke(JavassistLazyInitializer.java:68)
at org.jpwh.model.simple.Item_$$_jvst6d3_0.getName(Item_$$_jvst6d3_0.java)
at org.jpwh.test.stateless.CrudWithAssociations.lambda$fetchLazyAssociationForStackOverflow$6(CrudWithAssociations.java:94)
at org.jpwh.test.stateless.CrudWithAssociations$$Lambda$2/310350177.call(Unknown Source)
at org.jpwh.env.StatelessSessionTest.transaction(StatelessSessionTest.java:21)
at org.jpwh.test.stateless.CrudWithAssociations.fetchLazyAssociationForStackOverflow(CrudWithAssociations.java:90)
注意:
FetchType.EAGER
答案 0 :(得分:6)
不,当你使用StatelessSession
时没有持久化上下文(第一级缓存),因此延迟加载机制不起作用,因为许多延迟加载概念都是基于第一级缓存的存在。 / p>
例如,如果您有100个实体实例在多对一关联中引用相同的实体实例,则您将懒惰地重新加载引用的实例100次(对于每个引用实例)。
此外,许多延迟加载策略不起作用(例如,批量初始化,一旦访问未初始化的代理/集合,初始化多个代理/集合),因为Hibernate不会知道需要初始化的其他实例没有跟踪他们。
另一方面,StatelessSession
并不急切地获取任何被定义为惰性的东西,因为这可能导致在单个实体实例中获取大部分数据库。
解决方案是编写一个带有join fetch
子句的查询,以明确指定您需要加载的内容,或者您可以重新考虑使用经典Session
来受益于持久化上下文的所有优点