Конфигурация для возможности @Inject EntityManager в Seam 3
В моем проекте я использую Seam 3
, и у меня возникают проблемы с введением EntityManager
с помощью аннотации @Inject
. Я уверен, что есть какая-то конфигурация, чтобы убедиться, что EnityManager
знает, какой PersistenceUnit
использовать. Например, с помощью EJB
вы можете ввести:
@PersistenceContext(unitName="MY_PERSISTENCE_UNIT_NAME")
private EntityManager eManager;
в котором блок персистентности настроен в файле persistence.xml
. Вот моя псевдо-конфигурация:
<?xml version="1.0" encoding="UTF-8"?>
<persistence version="2.0"
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">
<persistence-unit name="MY_PERSISTENCE_UNIT_NAME" transaction-type="JTA">
<provider>org.hibernate.ejb.HibernatePersistence</provider>
<jta-data-source>java:jboss/TimeReportDS</jta-data-source>
<mapping-file>META-INF/orm.xml</mapping-file>
<class>....</class>
<class>....</class>
<class>....</class>
<properties>
<property name="jboss.entity.manager.factory.jndi.name"
value="java:/modelEntityManagerFactory" />
<!-- PostgreSQL Configuration File -->
<property name="hibernate.connection.driver_class" value="org.postgresql.Driver" />
<property name="hibernate.connection.password" value="password" />
<property name="hibernate.connection.url" value="jdbc:postgresql://192.168.2.125:5432/t_report" />
<property name="hibernate.connection.username" value="username" />
<!-- Specifying DB Driver, providing hibernate cfg lookup
and providing transaction manager configuration -->
<property name="hibernate.dialect" value="org.hibernate.dialect.PostgreSQLDialect" />
<property name="hibernate.transaction.factory_class" value="org.hibernate.transaction.JTATransactionFactory"/>
<property name="hibernate.transaction.manager_lookup_class"
value="org.hibernate.transaction.JBossTransactionManagerLookup" />
<property name="hibernate.archive.autodetection" value="class" />
<!-- Useful configuration during development - developer can see structured SQL queries -->
<property name="hibernate.show_sql" value="true" />
<property name="hibernate.format_sql" value="false" />
</properties>
</persistence-unit>
</persistence>
Я прочитал несколько статей о Seam 2, но там конфигурация сделана в файле components.xml
, добавив:
<persistence:managed-persistence-context
name="entityManager" auto-create="true" persistence-unit-jndi-name="java:/modelEntityManagerFactory" />
внутри тега <components>
. Следующим шагом в Seam 2 является добавление:
<property name="jboss.entity.manager.factory.jndi.name"
value="java:/modelEntityManagerFactory" />
в persistence.xml
<?xml version="1.0" encoding="UTF-8"?>
<persistence ...>
<persistence-unit name="MY_PERSISTENCE_UNIT_NAME" ...>
...
<properties>
...
<property name="jboss.entity.manager.factory.jndi.name"
value="java:/modelEntityManagerFactory" />
</properties>
</persistence-unit>
</persistence>
но это шов, что в Seam 3 нет файла components.xml
. Также нет атрибута unitName
в @Inject
аннотации для указания единицы сохранения.
Поэтому, пожалуйста, помогите мне настроить мой проект, чтобы я мог использовать @Inject
с EntityManager
, как показано во многих примерах в сети.
Я использую базу данных Postgres
и JBoss AS 7
.
EDIT: добавление примера. Я не использую EntityManager
в классе Entity
.
@Named("validateReportAction")
@SessionScoped
public class ValidateReportAction extends ReportAction implements Serializable {
private static final long serialVersionUID = -2456544897212149335L;
@Inject
private EntityManager em;
...
}
Здесь в этом @Inject
я получаю предупреждение от Eclipse
"No bean is eligible for injection to the injection point [JSR-299 §5.2.1]
"
Если я использую @Inject
на некотором beans, который помечен как Entity
, @Inject
отлично работает.
Ответы
Ответ 1
Вы можете использовать @PersistenceContext на CDI bean. Это не должно быть EJB.
Если по какой-то причине вы хотите использовать @Inject, вам нужно больше работать. @Inject не знает об EntityManager; он может вводить только другие управляемые beans. К счастью, есть простой способ - используйте метод продюсера, который действует как простой батут.
@ApplicationScoped
public class EntityManagerProducer {
@PersistenceContext
private EntityManager entityManager;
@Produces
@RequestScoped
public EntityManager getEntityManager {
return entityManager;
}
public void closeEntityManager(@Disposes EntityManager em) {
if (em != null && em.getTransaction().isActive()) {
em.getTransaction().rollback();
}
if (em != null && em.isOpen()) {
em.close();
}
}
}
Теперь вы можете использовать @Inject для ввода EntityManager. Введенный EntityManager будет запрашиваться, а EntityManagerProducer - ApplicationScoped. Кроме того, entityManager должен быть закрыт.