在Singleton的PreDestroy方法中访问无状态EJB

时间:2016-09-01 13:41:20

标签: java java-ee ejb-3.1

我在单例的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。

提前致谢

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批注声明其依赖性。原始海报提供的示例应该有效。