JSF + Hyperjaxb3 + Hibernate LazyInitializationException по запросам - PullRequest
0 голосов
/ 24 сентября 2010

У меня есть приложение JSF с компонентами тринидада и объектными компонентами JAXB / JPA, сгенерированными Hyperjaxb3. В пользовательском интерфейсе я использую компонент комбинированного поля Trinidad, в котором в качестве значений используется объект JPA.

Сценарий:

  1. Пользователь делает выбор в поле со списком
  2. Пользователь нажимает на элемент управления, который отправляет запрос на сервер и возвращается в ту же форму
  3. Данные из формы были отправлены, и выбор в поле со списком должен быть таким же, как пользователь на шаге 1. Метод equals () вызывается для элементов поля со списком (объекты JPA), и выдается это исключение:

org.hibernate.LazyInitializationException: не удалось лениво инициализировать коллекцию ролей: package.AnObject.items, ни один сеанс или сеанс не был закрыт в org.hibernate.collection.AbstractPersistentCollection.throwLazyInitializationException (AbstractPersistentCollection.java:358) at org.hibernate.collection.AbstractPersistentCollection.throwLazyInitializationExceptionIfNotConnected (AbstractPersistentCollection.java:350)

 at org.hibernate.collection.AbstractPersistentCollection.readSize(AbstractPersistentCollection.java:97)

 at org.hibernate.collection.PersistentBag.size(PersistentBag.java:225)

 at org.jvnet.hyperjaxb3.item.AbstractItemList.size(AbstractItemList.java:51)

 at java.util.AbstractList$Itr.hasNext(Unknown Source)

 at org.jvnet.jaxb2_commons.lang.builder.JAXBEqualsBuilder.append(JAXBEqualsBuilder.java:57)

 at org.jvnet.jaxb2_commons.lang.builder.JAXBEqualsBuilder.append(JAXBEqualsBuilder.java:29)

 at package.AnObject.equals(AnObject.java:177)

 at org.jvnet.jaxb2_commons.lang.builder.JAXBEqualsBuilder.append(JAXBEqualsBuilder.java:34)

 at package.ParentObject.equals(ParentObject.java:532)

 at package.ParentObject.equals(ParentObject.java:551)

 at java.util.ArrayList.indexOf(Unknown Source)

 at org.apache.myfaces.trinidad.component.UIXSelectMany._destructiveCompareOutOfOrderLists(UIXSelectMany.java:179)

 at org.apache.myfaces.trinidad.component.UIXSelectMany.compareValues(UIXSelectMany.java:139)

 at org.apache.myfaces.trinidad.component.UIXEditableValue.validate(UIXEditableValue.java:180)

 at org.apache.myfaces.trinidad.component.UIXEditableValue._executeValidate(UIXEditableValue.java:503)

 at org.apache.myfaces.trinidad.component.UIXEditableValue.processValidators(UIXEditableValue.java:270)

 at javax.faces.component.UIComponentBase.processValidators(UIComponentBase.java:1058)

 at javax.faces.component.UIComponentBase.processValidators(UIComponentBase.java:1058)

Я использую OpenEntityManagerInViewFilter из Spring для получения отложенных загруженных объектов - это работает в одном запросе.

На уровне сгенерированного объекта HyperJAXB equals() метод вызывает equals(Object object, EqualsBuilder equalsBuilder) метод, где equalsBuilder.append(...) вызывается для каждого атрибута этого объекта. Когда этот атрибут является списком, он передается через PersistenBag, и именно в этот момент я получаю исключение LazyInitializationException.

equals() метод - генерируется HyperJaxb:

public boolean equals(Object object) {
    if (!(object instanceof ParentObject)) {
        return false;
    }
    if (this == object) {
        return true;
    }
    final EqualsBuilder equalsBuilder = new JAXBEqualsBuilder();
    equals(object, equalsBuilder);
    return equalsBuilder.isEquals();
}

equals(Object object, EqualsBuilder equalsBuilder), сгенерированный HyperJaxb:

public void equals(Object object, EqualsBuilder equalsBuilder) {
    if (!(object instanceof ParentObject)) {
        equalsBuilder.appendSuper(false);
        return ;
    }
    if (this == object) {
        return ;
    }
    final ParentObjectthat = ((ParentObject) object);
    // PersitentBag, LazyInitializationException is thrown here
    equalsBuilder.append(this.getAnObject(), that.getAnObject());
    equalsBuilder.append(this.get..., that.get...);
    ...
}

У вас, ребята, есть идеи, как решить эту проблему?

Я пытался использовать JSF-конвертер и выбрал SelectItem со значением String (не объектом), но, если я помню, вызывается метод right equals () после преобразования String в мой объект.

1 Ответ

1 голос
/ 25 сентября 2010

Вы получаете это, потому что ваши объекты не отделены (1), и вы получаете доступ к данным (2) вне сеанса (3).Чтобы исправить, вы должны обратиться к (1-3) в любой комбинации.

  1. Отделите ваши объекты.Это, вероятно, самый простой способ, но загрузка не ленивая.
  2. Убедитесь, что сеанс доступен.Вы говорите, что используете шаблон OEMIV - как получается, что сеанса нет, когда вызывается метод equals?Я полагаю, это потому, что метод equals вызывается не во время рендеринга вида, а в некоторых других фазах JSF.Вы можете попытаться расширить шаблон OEMIV, чтобы он охватывал весь жизненный цикл JSF.
  3. Не обращайтесь к данным.Методы equals (...) и hashCode (...) рекомендуются, но не обязательны.Вы можете отключить их генерацию в HJ3, вы можете исключить определенные свойства из здания hashCode () / equals (...), вы можете использовать свои собственные стратегии equals и hashCode - множество способов добиться этого.

Я лично, я бы сначала проверил, почему сеанса там нет.

...