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

Accessing stateless EJBs in PreDestroy method of Singleton

我在单例的 preDestroy 方法中访问无状态 EJB 时遇到问题。我需要在数据库 table 中记录应用程序服务器的关闭。

这是单例的样子:

  @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。

提前致谢

@predestroy 应该只做 ejb 资源清理,例如连接、变量等...

您的问题与事务上下文有关,事实上来自规范:

The PreDestroy lifecycle callback interceptor methods for stateless and stateful session beans execute in an unspecified transaction context.

然后:

For example, it would be wrong to perform database operations within a stateful session bean’s PostConstruct or PreDestroy lifecycle callback interceptor methods and to assume that the operations are part of the client’s transaction. The PostConstruct and PreDestroy methods for stateful and stateless session beans are not controlled by a transaction attribute because handling rollbacks in these methods would greatly complicate the session instance’s state diagram.

因此,并未明确禁止,但会警告您可能会出错。

根据 ejb 3.2 规范,允许单例 bean 在 ejb 的预销毁方法中访问它。 See section 4.8.6 Table 3. 如果一个单例bean 需要访问另一个单例bean,那么它必须使用@DependsOn 注解来声明它的依赖关系。原发布者提供的示例应该有效。