RRR_J
RRR_J

Reputation: 347

JPA CascadeType.REFRESH not working?

I am facing a strange issue with JPA CascadeType.REFRESH attribute. I have a simple parent-child relationship in which in parent domain object(LineEquipmentFormat) I have added the cascade attributes like below

OneToMany(cascade = { CascadeType.REFRESH, CascadeType.MERGE, CascadeType.PERSIST,
   CascadeType.REMOVE}, mappedBy = "lineEquipmentFormat")
 public List<LineEquipmentFormatDivision> getLineEquipmentFormatDivisions() {
  return lineEquipmentFormatDivisions;
 }

But when I fetch the parent LineEquipmentFormat object from DB, I do not get the list of LineEquipmentFormatDivisions.

Error I am getting is

  17:46:34,251 ERROR [LazyInitializationException] failed to lazily initialize a collection of role: LineEquipmentFormat.lineEquipmentFormatDivisions, no session or session was closed
    org.hibernate.LazyInitializationException: failed to lazily initialize a collection of role: LineEquipmentFormat.lineEquipmentFormatDivisions, no session or session was closed
     at org.hibernate.collection.AbstractPersistentCollection.throwLazyInitializationException(AbstractPersistentCollection.java:380)
     at org.hibernate.collection.AbstractPersistentCollection.throwLazyInitializationExceptionIfNotConnected(AbstractPersistentCollection.java:372)
     at org.hibernate.collection.AbstractPersistentCollection.initialize(AbstractPersistentCollection.java:365)
     at org.hibernate.collection.AbstractPersistentCollection.read(AbstractPersistentCollection.java:108)
     at org.hibernate.collection.PersistentBag.toString(PersistentBag.java:506)

I am using Jboos 5.1 and Oracle 10G.

Please provide more inputs on possible root cause of this error.

Thanks

Upvotes: 1

Views: 4067

Answers (3)

RRR_J
RRR_J

Reputation: 347

Thanks for your comments.

Here is how we have finally implemented it.

  1. While fetching the "LineEquipmentFormat" parent object we have added following additional code.

    LineEquipmentFormat lef = entityManager.find(LineEquipmentFormat.class, sysId); if (lef != null && lef.getLineEquipmentFormatDivisions() != null) { lef.getLineEquipmentFormatDivisions().size(); }
    return lef;

  2. Now if we can fetch the child list from this parent object.

Upvotes: 0

Pascal Thivent
Pascal Thivent

Reputation: 570545

I have added the cascade attributes like below (...) But when I fetch the parent LineEquipmentFormat object from DB, I do not get the list of LineEquipmentFormatDivisions.

Cascading operations has little to do with EAGER or LAZY loading and in your case, the error you are getting (the infamous LazyInitializationException) means that you are trying to access a lazy association but that the session has already been closed (so Hibernate can't load it).

To avoid this "problem", either:

  • eager load the association using the fetchType attribute (that's IMO putting "lipstick on the pig" if you don't need the association in most scenario)
  • use a FETCH JOIN for this particular use case to fetch the association while executing queries, eg:

    SELECT f
    FROM LineEquipmentFormat f LEFT JOIN FETCH f.lineEquipmentFormatDivisions
    WHERE f.id = 1
    
  • use the Open EntityManager In View pattern (in a MVC context) to open the entity manager when a request comes in and keep it open until the request has been handled (Spring has a Serlvet filter or an Interceptor implementing this pattern).

Upvotes: 1

hakan
hakan

Reputation: 1851

When you define the cascade type as refresh, that means when the entityManager.refresh() is called on the parent LineEquipmentFormat, it will be also called on the child LineEquipmentFormatDivisions. However, the error that you are getting indicates that you tried to lazily initialize the collection while the session is closed. If you need this collection after the session is closed, you need to fetch them eagerly by setting the fetchType.

Upvotes: 2

Related Questions