休眠会话已经过去了

时间:2011-09-08 20:53:00

标签: hibernate session ejb

我在奇怪的条件下面对懒惰的初始化。

  1. 事务:获取持久对象的底层实体。
  2. 事务:获取非持久对象的底层实体。
  3. 事务:合并持久对象。然后坚持下去 非持久对象抛出异常。

    javax.persistence.PersistenceException:org.hibernate.LazyInitializationException:无法初始化代理 - 没有会话。

  4. 在持久化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.)
    }
    
    拥有的GeoObjects和创建者可以由用户创建或者找到并添加到列表中作为存在(持久)。所有存在的和用户创建的实体都存储在事务(人员字段)之间的有状态bean中。并完全取得了他们分开的交易。然后,所有结构的持久化来自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);
             }
          }
       }
    
    }
    

    如果其中一个拥有的GeoObject是持久的而另一个不是。

    ,则抛出异常
    at ru.vetrf.cerberus.ejb.GeoObjectManager.addGeoObject(GeoObjectManager.java:119)
    

    这一行是

    addressManager.addAddress(geoObject.getAddress());
    

    在持久性GeoObject的更新(合并)之后,似乎会话已经消失(对于非持久性GeoObject及其地址)。为什么会这样? 其他场景(一个存在,一个新的,多个存在的,多个新的)传递良好。 创始人名单不受此问题的影响。

    P.S。可以认为添加/更新方法仅包含持久化/合并。

1 个答案:

答案 0 :(得分:1)

这是问题,您在事务之间移动具有未初始化代理的对象。这就是抛出这样的错误的地方:当你访问代理服务器(例如带有延迟加载的列表)时,当加载对象的事务被关闭时。

考虑一下你是否真的需要延迟加载,如果是这样,请确保在关闭事务之前加载所有代理(例如,person.getOwners()。size())