0

Hyperjaxb3によって生成されたトリニダードコンポーネントとJAXB/JPAエンティティBeanを備えたJSFアプリケーションがあります。UIでは、JPAオブジェクトを値として持つTrinidadコンボボックスコンポーネントを使用します。

シナリオは次のとおりです。

  1. ユーザーはコンボボックスで選択を行います
  2. ユーザーがサーバーにリクエストを送信し、同じフォームに返されるコントロールをクリックします
  3. フォームからのデータが送信され、コンボボックスでの選択は、ユーザーが手順1で行ったとおりにする必要があります。equals()メソッドがコンボボックスアイテム(JPAオブジェクト)で呼び出され、次の例外がスローされます。

org.hibernate.LazyInitializationException:ロールのコレクションを遅延初期化できませんでした:package.AnObject.items、org.hibernate.collection.AbstractPersistentCollection.throwLazyInitializationException(AbstractPersistentCollection.java:358)atorg.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)

SpringのOpenEntityManagerInViewFilterを使用して、遅延ロードされたオブジェクトを取得します。これは1つのリクエストで機能します。

HyperJAXBで生成されたオブジェクトのレベルでは、メソッドはそのオブジェクトの各属性で呼び出されるメソッドequals()を呼び出します。その属性がリストである場合、それはPersistenBagによってプロキシされ、それがLazyInitializationExceptionを取得するポイントです。equals(Object object, EqualsBuilder equalsBuilder)equalsBuilder.append(...)

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コンバーターを使用して、String値(オブジェクトではない)を持つSelectItemを使用しようとしましたが、覚えていれば、Stringがオブジェクトに変換された後にequals()が呼び出されます。

4

1 に答える 1

1

これは、オブジェクトが切り離されておらず(1)、セッション外でデータ(2)にアクセスしているためです(3)。修正するには、(1〜3)を任意の組み合わせでアドレス指定する必要があります。

  1. オブジェクトを切り離します。これはおそらく最も簡単ですが、遅延読み込みではありません。
  2. セッションが利用可能であることを確認してください。OEMIVパターンを使用しているとおっしゃっていますが、equalsメソッドが呼び出されたときにセッションが存在しないのはなぜですか?これは、ビューのレンダリング中ではなく、他のJSFフェーズでequalsが呼び出されるためだと思います。OEMIVパターンを拡張して、JSFライフサイクル全体にまたがるようにすることができます。
  3. データにアクセスしないでください。equals(...)メソッドとhashCode(...)メソッドをお勧めしますが、必須ではありません。HJ3での生成を無効にしたり、hashCode()/ equals(...)の構築から特定のプロパティを除外したり、独自のequalsおよびhashCode戦略を使用したりできます。これを実現する方法はたくさんあります。

私個人的には、最初に確認しますが、なぜセッションがないのですか。

于 2010-09-25T17:34:03.887 に答える