我在单例的preDestroy方法中访问无状态EJB时遇到问题。我需要在数据库表中记录应用程序服务器的关闭。
这就是单身人士的样子:
@Startup
@Singleton
public class ServerShutdown {
@EJB
TableFacade tableFacade;
@PreDestroy
private void shutdown() {
TestEntity e = tableFacade.find("test");
//do something
}
}
这是无状态bean的示例代码:
@Stateless
public class TableFacade {
...
public TestEntity find(String test) {
Query query =
getEntityManager().createNamedQuery("TestEntity.namedQuery");
return (TestEntity) query.getSingleResult();
}
}
如果服务器正在关闭,则访问preDestroy方法并调用EJB方法。但是在调用期间,服务器似乎强制关闭进程并取消调用EJB方法。
我正在使用Java EE 6,JDK 1.8,EJB 3.1,eclipselink 2.5.2。
提前致谢
答案 0 :(得分:1)
@predestroy
应该只进行ejb资源清理,例如连接,变量等......
您的问题与事务上下文有关,事实上来自规范:
无状态的PreDestroy生命周期回调拦截器方法 和有状态会话bean在未指定的事务中执行 上下文。
然后:
例如,在a中执行数据库操作是错误的 有状态会话bean的PostConstruct或PreDestroy生命周期回调 拦截器方法并假设操作是其中的一部分 客户的交易。 PostConstruct和PreDestroy方法 有状态和无状态会话bean不受a控制 事务属性,因为在这些方法中处理回滚 会使会话实例的状态图大大复杂化。
所以,它没有被明确禁止,但是你被警告说事情可能会出错。
答案 1 :(得分:0)
根据ejb 3.2规范,允许单例bean以其pre destroy方法访问ejb。请参阅第4.8.6节表3。如果一个单例bean需要访问另一个单例bean,则它必须使用@DependsOn批注声明其依赖性。原始海报提供的示例应该有效。