2

Consider the data model from "Java Persistence with Hibernate" where a Bid has a lazy association to Item:

@ManyToOne(optional = false, fetch = FetchType.LAZY) // NOT NULL
@JoinColumn(name = "ITEM_ID") // Actually the default name
protected Item item;

and then the following snippet that tries to load a Bid through a StatelessSession and then access the associated Item:

        Bid bid = (Bid) statelessSession.get(Bid.class, bidId);
        assertNotNull(bid.getItem());
        assertEquals(bid.getItem().getName(), "Bike");

This throws a LazyInitializationException, even though the session is still active. Can we infer from here that lazy loading is not supported in conjunction with 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)

NOTES:

  • The code works fine if I change the association to FetchType.EAGER
  • I've tested this on Hibernate 5.0.6.
Bogdan Calmac
  • 7,993
  • 6
  • 51
  • 64
  • check this [answer](http://stackoverflow.com/questions/18593736/hibernate-save-lazily-fetched-entity-via-stateless-session) Hope this helps. – jmj Jan 14 '16 at 22:59

1 Answers1

7

No, there is no persistence context (first level cache) when you use StatelessSession, thus lazy loading mechanism does not work, because lots of lazy loading concepts are based on the existence of the first level cache.

For example, if you have 100 entity instances all referencing the same entity instance in a many-to-one association, you would lazy re-load the referenced instance 100 times (for each referencing instance).

Also, many lazy loading strategies would not work (for example, batch initializing where you initialize multiple proxies/collections once you access an uninitialized proxy/collection), because Hibernate would not be aware of the other instances that need to be initialized without tracking them.

On the other hand, StatelessSession does not fetch eagerly anything that is defined as lazy, because that could lead to fetching a large portion of database within a single entity instance.

The solution is to write a query with join fetch clauses to explicitly specify what you need to be loaded, or you could reconsider using classic Sessions to benefit from all of the advantages of the persistence context.

Dragan Bozanovic
  • 23,102
  • 5
  • 43
  • 110
  • I don't understand the reason behind the first statement. Why would you need the cache for lazy loading? Initially you create a proxy that holds the ID of the entity and when it is referred you hit the DB, load the entity and update the proxy. All you need here is the ID of the entity and a DB connection. – Bogdan Calmac Jan 15 '16 at 15:00
  • @BogdanCalmac I edited my answer. Lazy loading does not make sense without the first-level cache and would completely degrade the performance (thus annihilating any benefits introduced by the `StatelessSession` in the first place). – Dragan Bozanovic Jan 15 '16 at 16:48
  • Thanks. I wouldn't say that it doesn't make sense though. Just like everything with Hibernate, there will be cases when performance is severely degraded and the use of a certain feature is not recommended. In my practical use case that prompted this question the performance would have been optimal. – Bogdan Calmac Jan 15 '16 at 17:07
  • I also think that this is important enough to be documented. Both the Hibernate documentation and Java Persistence with Hibernate only mention that collections are ignored. http://docs.jboss.org/hibernate/orm/4.3/devguide/en-US/html_single/#d5e1101 – Bogdan Calmac Jan 15 '16 at 17:11
  • I agree, there are exceptions for every general rule/pattern. Especially I agree about the documentation, but keep in mind that Hibernate is an open-source product; feel free to contribute with the implementation/documentation. :) – Dragan Bozanovic Jan 15 '16 at 17:20