tags:

views:

36

answers:

2

Hi All,

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

+1  A: 

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.

hakan
But I didn't get your point on session. If I am doing this fetch of LineEquipmentFormat in one transaction and immediately on next line if I try to get the list of divisions then surely session is not closed rt? Also we have been discouraged to use fetchType attributes so that option is ruled out!
RRR_J
If you need the child members everytime you initialized the parent object then there is no problem of setting fetchType as eager. If this is not the case, you need to fetch them eagerly only when you need them for which you can make a query with a fetch join. If you post the code where you query the LineEquipmentFormat and where you try to access LineEquipmentFormatDivisions, we might be more helpful. If you are for example saying entityManager.find(LineEquipmentFormat.class,id), the session is get opened and closed within this method.
hakan
A: 

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).

Pascal Thivent