сессия спящего режима прошла - PullRequest
1 голос
/ 09 сентября 2011

Я столкнулся с ленивым инициалом в странных условиях.

  1. Транзакция: выборка базовых объектов персистентного объекта.
  2. Транзакция: выборка базовых объектов непостоянного объекта.
  3. Транзакция: объединение постоянного объекта. Тогда сохранятся непостоянный объект вызывает исключение.

    javax.persistence.PersistenceException: org.hibernate.LazyInitializationException: не удалось инициализировать прокси - нет сеанса.

Выдается при сохранении сложного объекта класса 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.)
}

ownGeoObjects и основатели могут быть созданы пользователем или найдены и добавлены в списки как существующие (постоянные). Все существующие и созданные пользователем объекты хранятся в компоненте с отслеживанием состояния между транзакциями (поле person). И полностью извлечены из их отдельных транзакций. Тогда сохранение всех структур происходит из 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);
         }
      }
   }

}

Исключение выдается, если один из принадлежащих GeoObjects является постоянным, а другой - нет.

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

эта строка

addressManager.addAddress(geoObject.getAddress());

Кажется, что сессия прошла (для непостоянного GeoObject и его адреса) после обновления (слияния) постоянного GeoObject. Почему это могло случиться? Другие сценарии (один существующий, один новый, несколько существующих, несколько новых) проходит хорошо. И этот список не влияет на список учредителей.

p.s. можно считать, что методы добавления / обновления состоят только из постоянных / слияния.

1 Ответ

1 голос
/ 09 сентября 2011

Проблема в том, что вы перемещаете объекты с неинициализированными прокси между транзакциями.Вот где возникает такая ошибка: когда вы обращаетесь к прокси (например, список с отложенной загрузкой), когда транзакция, в которой был загружен объект, закрыта.

Рассмотрите, действительно ли вам нужна отложенная загрузка, если это так,убедитесь, что все прокси загружены до закрытия транзакции (fg person.getOwners (). size ())

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...