EJB 注释不起作用

EJB annotation not working

我的 EJB 注释有问题:

我有一个 DAO:

@Singleton
@Startup
public class CassandraDAO<T extends Serializable> extends AbstractDAO {

  @PersistenceContext(unitName = "JPAService", type = PersistenceContextType.EXTENDED)
  private EntityManager em;

  @PostConstruct
  public void init() {
    System.out.println("***************** init CassandraDAO ***************************");
  }

  @PreDestroy
  public void destroy() {
    System.out.println("***************** destroying CassandraDAO *************************");
    if (em.isOpen()) {
      em.close();
    }
  }

  @Override
  public EntityManager getManager() {
    return em;
  }

  @Override
  public void setManager(EntityManager em) {
    this.em = em;
  }
}

并且有几个 DAO 扩展了这个 DAO:

@Stateless
public class IOConfigurationDAO extends CassandraDAO<IOConfiguration> {
...
}

下面是我使用 DAO 的方式:

public class AddAlertTest extends TestCase {
  @EJB
  private IOConfigurationDAO ioConfigurationDAO;
  public void test() {
      ioConfigurationDAO.getManager().getTransaction().begin();
      IOConfiguration ioConfig = new IOConfiguration("CH1");
      ioConfigurationDAO.getManager().persist(ioConfig);
      ioConfigurationDAO.getManager().getTransaction().commit();
      int oldSize = ioConfig.getAlerts() == null ? 0 : ioConfig.getAlerts().size();
      System.out.println("Created IO configuration with id " + ioConfig.getIoConfigurationId());

      ioConfigurationDAO.getManager().getTransaction().begin();
      Alert alert = ioConfigurationDAO.addAlert(ioConfig,
          Operators[(int) (Math.random() * Operators.length)], new Double(Math.random() * 100));
      ioConfigurationDAO.getManager().getTransaction().commit();
      int newSize = ioConfig.getAlerts().size();
      System.out.println("Created new Alert with id " + alert.getAlertId());
      System.out.println("Alert list: " + ioConfig.getAlerts());
      System.out.println("Alert is connected to " + alert.getIoConfiguration());

      assertEquals(oldSize + 1, newSize);
      assertNotNull(ioConfigurationDAO.getManager().find(Alert.class, alert.getAlertId()));

      ioConfigurationDAO.getManager().getTransaction().begin();
      ioConfigurationDAO.getManager().remove(ioConfig);
      ioConfigurationDAO.getManager().getTransaction().commit();
      System.out.println("Deleted IO configuration with id " + ioConfig.getIoConfigurationId());
  }

但是我的 IOConfigurationDAO 总是空的,所以我的 persistenceContext 注释根本不起作用。而且我的控制台中没有打印出任何内容,所以我的 postConstruct 注释也不起作用。

这是我的 persistence.xml:

<?xml version="1.0"?>
<persistence xmlns="http://java.sun.com/xml/ns/persistence"
             xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
             xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd"
             version="2.0">        
    <persistence-unit name="JPAService">            
        <provider>org.hibernate.ogm.jpa.HibernateOgmPersistence</provider>    
        <class>com.sensorhound.aigateway.domain.Alert</class>
        <class>com.sensorhound.aigateway.domain.DataSeriesMeta</class>
        <class>com.sensorhound.aigateway.domain.IOConfiguration</class>
        <class>com.sensorhound.aigateway.domain.NodeData</class>
        <properties>
            <property name="hibernate.transaction.jta.platform" value="JBossAS" />
            <property name="jboss.as.jpa.providerModule" value="org.hibernate:5.0" />
            <property name="hibernate.ogm.datastore.provider" value="cassandra_experimental"/>
            <property name="hibernate.ogm.datastore.host" value="127.0.0.1:9042"/>
            <property name="hibernate.ogm.datastore.database" value="dev"/>
            <property name="hibernate.hbm2ddl.auto" value="none"></property>
            <property name = "hibernate.show_sql" value = "true" />
            <property name = "hibernate.format_sql" value = "true" />
        </properties>
    </persistence-unit>
</persistence>

我不知道我的配置有什么问题。有人请帮助我。如果您需要更多信息,我愿意分享。

谢谢!

当一个EJB A扩展另一个EJB B时,通过注入使用B的客户端不会自动继承上层class A的所有方法。实际上通过代理访问EJB临时创建。

换句话说,如果您注入 IOConfigurationDAO,您正在使用那个 class 的代理,扩展 class 的所有其他业务方法对客户端不可见。生命周期 @PostConstruct 等不会被调用。

此外,这个设计对我来说看起来很奇怪,一个继承自@Singleton 的@Stateless。

容器所做的 DI 注释(@Inject、@EJB、@PersistenceContext 等)的工作。当你运行一个单元测试时,测试运行出容器。因此可注入属性保持为空。对于单元测试,总是模拟这种依赖关系。了解一些有关托管 bean(CDI、JSF)、单元测试和 Mocking 的知识。

我无法让 EJB 在我的单元测试中工作。但是我让我的 EJB 在项目中工作。我只是切换到有状态 EJB,因为我的 DAO 正在数据库中进行一些修改,并将我在 DAO 的父 class 中拥有的方法复制到 DAO。谢谢!