gpt4 book ai didi

java - bean 属性上的 SEAM JSF Lazy Init 异常

转载 作者:行者123 更新时间:2023-12-01 04:56:27 26 4
gpt4 key购买 nike

我在 SEAM (2.2.2) 应用程序中遇到了延迟初始化异常的问题,我正在使用 SEAM 托管持久性上下文(使用 JPA),如此处的文档中所述

SEAM 文档引用。 9.3.1 SEAM Managed Persistance Context with JPA

在我的 GenericDAO 类中使用 @In 注入(inject)实体管理器

场景:

我有一个对话范围的 bean,它注入(inject)当前登录的用户实体( session 范围),当我尝试通过页面中的 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

起初我以为对话可能超时了,但这是通过注销用户来处理的,而不是抛出谎言

所以现在我想,也许因为用户实体是从 session 范围注入(inject)的,而操作 bean 是 session 范围的,所以对象以某种方式与实体管理器分离?

不幸的是,异常并不是每次都会抛出,所以我无法轻松地重现它(应用程序是实时的,所以我会随时收到错误)

我知道我可以通过将用户属性设置为“急切加载”来解决这个问题,但我想首先深入了解这个问题,并且不希望预先加载所有实体

有关我的设置的更多详细信息:

组件.xml:

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

持久性.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>

通用DAO

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
}

最佳答案

如果您从操作 bean 获取用户实体,请尝试在您的操作 bean 中

用户 user=entityManger.find(User.class,User.getId());

这应该将其加载到扩展持久性上下文中,因为它看起来像是分离的

发表评论后编辑

您当然不会在 getter 方法中执行此操作,只需在访问 bean 之前的任何方法中执行一次,它将附加到您的扩展 PC,我会说在操作 bean 的 @Create 方法中执行此操作。关于你的最后一个问题:它是否曾经被加载到Seam管理的 session 绑定(bind)的持久上下文中?

此外,您还应该使用“@In EntityManagerEntityManager”注入(inject)实体管理器,因为这是您在 application.xml 中托管持久性上下文的配置。如果您的实体曾经在此对话中加载到 EPC 中,那么就足够了。

关于java - bean 属性上的 SEAM JSF Lazy Init 异常,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14040537/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com