[英]@Remote EJB which uses @RequestScoped CDI bean
我有一个具有@Remote @Singleton
EJB的应用程序,该应用程序注入了由CDI生成的@RequestScoped
实体管理器。 同一服务器(wildfly 9)/ JVM上的另一个应用程序将使用此EJB从实体管理器获取结果。
EJB的第一次调用将返回预期的结果。 它产生实体管理器,获取数据,并在调用返回时再次处置实体管理器。 由于关闭了实体管理器,因此对该EJB的每次后续调用都将引发错误。 没有为新的实体经理生产/处置的产品。
这是预期的行为吗? 我的代码中有错误吗?
IFrameworkResourceManager framework = _applicationContext.getFrameworkResourceManager();
final User resolvedUser = framework.resolveUser(username, domain);
// ...
final Rights resolvedRights = framework.resolveRights(resolvedUser.getGuid(), applicationId);
// ...
这段代码在CDI生产者中执行,一旦为用户创建了新的http会话,该代码就会再次执行。 如果在调用resolveRights
之前再次调用getFramworkResourceManager
,则没有任何改变。
public IFrameworkResourceManager getFrameworkResourceManager() {
return IFrameworkResourceManager frm = (IFrameworkResourceManager) ctx
.lookup("java:global/WebFramework/WebFrameworkImpl!my.package.IWebFramework");
}
我使用直接JNDI查找还是@EJB
注入都没关系。 返回的实例被报告Proxy for remote EJB StatelessEJBLocator for "/WebFramework/WebFrameworkImpl", view is interface my.package.IWebFramework, affinity is None
) Proxy for remote EJB StatelessEJBLocator for "/WebFramework/WebFrameworkImpl", view is interface my.package.IWebFramework, affinity is None
( toString()
) Proxy for remote EJB StatelessEJBLocator for "/WebFramework/WebFrameworkImpl", view is interface my.package.IWebFramework, affinity is None
@LocalBean
@Singleton
public class WebFrameworkImpl implements IWebFramework, Serializable {
@Inject
private EntityManager _entityManager;
@Override
public User resolveUser(String username, String domain) {
System.out.println(_entityManager + " || " + _entityManager.isOpen());
// execute query using QueryDSL and the injected entityManager
}
@Override
public Rights resolveRights(String guidUser, int applicationId) {
System.out.println(_entityManager + " || " + _entityManager.isOpen());
// execute query using QueryDSL and the injected entityManager
}
}
@Remote
public interface IWebFramework extends IFrameworkResourceManager {
// some methods...
}
public interface IFrameworkResourceManager {
public User resolveUser(String username, String domain);
public Rights resolveRights(String guidUser, int applicationId);
}
解决用户的resolveUser
: org.hibernate.jpa.internal.EntityManagerImpl@379e882b || true
org.hibernate.jpa.internal.EntityManagerImpl@379e882b || true
Sysout的resolveRights
: org.hibernate.jpa.internal.EntityManagerImpl@379e882b || false
org.hibernate.jpa.internal.EntityManagerImpl@379e882b || false
编辑20.11.2015 13:43 :持久性单元的类型为RESOURCE_LOCAL
。 此外,所有@ResourceScoped
Bean均会受到影响。 @PostConstruct
和@PreDestroy
仅在第一次EJB调用时被调用。 每次后续调用都使用资源范围Bean的先前实例,该实例不正确。
编辑20.11.2015 13:55 :如果从提供EJB的同一应用程序中调用EJB,一切都会按预期工作。 仅当从其他应用程序进行调用时,才会出现此行为。
编辑20.11.2015 15 :24:JBoss AS 7.1.3.Final,Wildfly 9.0.0.Final和Wildfly 10.0.0.CR4均生效。 但是根据CDI规范(1.0至1.2)第6.7.4章,这应该可行。 我已经填写了一个错误报告(WFLY-5716)。
使用RESOURCE_LOCAL
,应从EntityManagerFacgtory创建您的EntityManager并自行处理,例如:
private EntityManagerFactory factory = Persistence.createEntityManagerFactory("unit-name");
public void someMethod(){
EntityManager em = emf.createEntityManager();
EntityTransaction tx = null;
try {
tx = em.getTransaction();
tx.begin();
// do some work
tx.commit();
}
catch (RuntimeException e) {
if ( tx != null && tx.isActive() )
tx.rollback();
throw e; // or display error message
}
finally {
em.close();
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.