1

SEAM(2.2.2)アプリケーションでレイジー初期化例外の問題が発生しています。ここのドキュメントで説明されているSEAM管理の永続コンテキスト(JPAを使用)を使用しています

SEAMDocsRef。9.3.1JPAを使用したSEAMマネージド永続コンテキスト

これにより、エンティティマネージャーは私のG​​enericDAOクラスで@Inを使用して注入されます

シナリオ:

現在ログインしているユーザーエンティティ(セッションスコープ)を挿入する会話スコープのBeanがありますが、ページのJSF(el)を介して追加のユーザー属性を遅延ロードしようとすると、LIEがスローされるようです。

スタックトレースエラー:

2012-12-24 15:30:34,661 SEVERE [facelets.viewhandler] (http-0.0.0.0-8080-3) Error Rendering View[/user/settings.xhtml]: javax.el.ELException: /user/settings.xhtml: org.hibernate.LazyInitializationException: could not initialize proxy - no Session

at com.webapp.entities.Client_$$_javassist_29.getLogoUrl

最初は会話がタイムアウトしたのではないかと思いましたが、これはLIEをスローするのではなく、ユーザーをログアウトすることで処理されます。

では、ユーザーエンティティがセッションスコープから挿入され、アクションBeanが会話スコープであるために、オブジェクトがエンティティマネージャーから何らかの形で切り離されているのではないかと思いました。

残念ながら、例外が毎回スローされるわけではないため、簡単に再現することはできません(アプリケーションはライブであるため、いつでもエラーが発生します)

EAGERLYをロードするようにユーザープロパティを設定することでこれを解決できることはわかっていますが、最初にこれの一番下に行きたいので、すべてのエンティティを前もってロードしたくないです

私のセットアップの詳細:

components.xml:

<persistence:managed-persistence-context name="entityManager"
    auto-create="true"
    persistence-unit-jndi-name="java:/EntityManagerFactories/appData">  
</persistence:managed-persistence-context>

persistence.xml

<persistence-unit name="AppDatabase">
    <provider>org.hibernate.ejb.HibernatePersistence</provider>
    <jta-data-source>java:/appDatasource</jta-data-source>
    <properties>
        <property name="hibernate.connection.datasource" value="java:/appDatasource"/>
        <property name="hibernate.dialect" value="org.hibernate.dialect.PostgreSQLDialect"/>
        <property name="jboss.entity.manager.factory.jndi.name" value="java:/EntityManagerFactories/appData"/>
        <property name="hibernate.cache.use_second_level_cache" value="false"/>
        <property name="hibernate.show_sql" value="false"/> 
    </properties>
</persistence-unit>

GenericDAO

public abstract class GenericDAOBean<T>
    implements GenericDAO<T>, Serializable{

private static final long serialVersionUID = 1L;

private Class<T> entityBeanType;

@In private EntityManager em;

@SuppressWarnings("unchecked")
public GenericDAOBean() {
    this.entityBeanType = (Class<T>) ((ParameterizedType) getClass()
                            .getGenericSuperclass()).getActualTypeArguments()[0];
}

/**
 * Set the entity manager to use
 * 
 * @param em
 */
public void setEntityManager(EntityManager em) {
    this.em = em;
}

/**
 * Get the current seam entity manager
 * 
 * @return
 */
 protected EntityManager getEntityManager() {
 //Seam entity manager set this way as of version 2.2.0 
 //can't handle abstract classes and @In doesn't inject
 //into this as a parent class
 EntityManager entityManager = (EntityManager)Component.getInstance("entityManager");
 if (entityManager == null)
     throw new IllegalStateException("Seam EntityManager has not been set on "
     +getEntityBeanType().getClass().getName()+"DAO before usage!");
     return entityManager;
 }

//Further Generic method follow here which are removed for brevity
}
4

1 に答える 1

0

アクションBeanからユーザーエンティティを取得する場合は、アクションBeanを試してください

ユーザーuser=entityManger.find(User.class、User.getId());

切り離されているように見えるため、拡張永続コンテキストにロードする必要があります

コメントの後で編集します。

確かに、getterメソッドでは実行しないでください。Beanへのアクセスに先行する任意のメソッドで一度実行すると、拡張PCに到達します。アクションBeanの@Createメソッドで実行すると思います。最後の質問について:会話にバインドされているSeam管理の永続コンテキストにロードされたことはありますか?

また、これはapplication.xmlでの管理された永続コンテキストの構成であるため、エンティティマネージャーに「@InEntityManagerentityManager」を挿入する必要があります。また、この会話内でエンティティがEPCにロードされたことがある場合は、それで十分です。

于 2012-12-28T02:53:43.190 に答える