开发者

hibernate session has gone

I've faced lazy init with strange conditions.

  1. Transaction: fetch of underlying entites of a persistent object.
  2. Transaction: fetch of underlying entites of a not persistent object.
  3. Transaction: merge of a persistent object. Then persist of a not persistent object throws an exception.

    javax.persistence.PersistenceException: org.hibernate.LazyInitializationException: could not initialize proxy - no Session.

Thrown when persisting complex object of class Person.

public class Person {
    protected List<Person> founders;
    protected List<GeoObject> ownedGeoObjects;
}

public class GeoObject {
    private List<Person> owners;
    private Address address; //complex lazy-fetched structure of pre-defined persistent entities (country, city, etc.)
}

ownedGeoObjects and founders may be created by user or found and added to lists as existent (persistent). All existent and开发者_运维百科 user-created entities are stored in stateful bean between transactions (person field). And completely fetched in their separated transactions. Then persisting of all structures comes from commitPerson():

@Stateful
public class SessionManager {

   private Person person;

   private Person commitPerson(Person person) {    
      personManager.addPerson(person);
      commitFounders(person.getFounders());
      commitGeoObjects(person);      
      return person;
   }

   private void commitFounders(List<Person> founders) throws ValidationError {
      for (Person founder : founders) {
         if (!founder.getPersistent()) {
            personManager.addPerson(founder);
         }
      }
   }

   private void commitGeoObjects(Person person) throws ValidationError {
      List<GeoObject> objects = person.getOwnedGeoObjects();
      for (GeoObject geoObject : objects) {
         refetch(geoObject); //this is my workaround
         geoObject.getOwners().add(person); //inverse relation        
         if (!geoObject.getPersistent()) {
            geoObjectManager.addGeoObject(geoObject);
         } else {
            geoObjectManager.updateGeoObject(geoObject);
         }
      }
   }

}

Exception is thrown if one of the ownedGeoObjects is persistent and other one is not.

at ru.vetrf.cerberus.ejb.GeoObjectManager.addGeoObject(GeoObjectManager.java:119)

this line is

addressManager.addAddress(geoObject.getAddress());

It seems like session has gone (for a not persistent GeoObject and its Address) after update (merge) of the persistent GeoObject. Why could that happen? Other scenarios (one existent, one new, multiple existent, multiple new) passes well. And list of founders is not affected by this issue.

p.s. it may be considered that add/update methods consist of persist/merge only.


This is the problem, that you are moving objects with uninitialized proxies between transactions. This is where such error is thrown: when you access proxy (f.g. the list with lazy-loading), when transaction where object was loaded is closed.

Consider if you really need lazy-loading, if so, make sure all proxies are loaded before closing transaction (f.g. person.getOwners().size())

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜