StatelessSession是否支持延迟加载?

时间:2016-01-14 22:13:51

标签: java hibernate

考虑“Java Persistence with Hibernate”中的数据模型,其中BidItem具有惰性关联:

@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
  • ,则代码可以正常工作
  • 我在Hibernate 5.0.6上测试了这个。

1 个答案:

答案 0 :(得分:6)

不,当你使用StatelessSession时没有持久化上下文(第一级缓存),因此延迟加载机制不起作用,因为许多延迟加载概念都是基于第一级缓存的存在。 / p>

例如,如果您有100个实体实例在多对一关联中引用相同的实体实例,则您将懒惰地重新加载引用的实例100次(对于每个引用实例)。

此外,许多延迟加载策略不起作用(例如,批量初始化,一旦访问未初始化的代理/集合,初始化多个代理/集合),因为Hibernate不会知道需要初始化的其他实例没有跟踪他们。

另一方面,StatelessSession并不急切地获取任何被定义为惰性的东西,因为这可能导致在单个实体实例中获取大部分数据库。

解决方案是编写一个带有join fetch子句的查询,以明确指定您需要加载的内容,或者您​​可以重新考虑使用经典Session来受益于持久化上下文的所有优点