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。谢谢!
我的 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。谢谢!