Конфигурация для возможности @Inject EntityManager в Seam 3 - PullRequest
3 голосов
/ 06 января 2012

В моем проекте я использую 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> тег.Следующим шагом в шве 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>

, но это шов, что в шве 3 нет файла components.xml.Также нет атрибута unitName в аннотации @Inject для указания единицы сохраняемости.

Поэтому, пожалуйста, помогите мне настроить мой проект, чтобы я мог использовать @Inject с EntityManager, как показано во многих примерах в сети.

Я использую Postgres базу данных и JBoss AS 7.

РЕДАКТИРОВАТЬ: Добавление примера.Я не использую 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 на некоторых бобах, помеченных как Entity, @Inject работает нормально.

1 Ответ

5 голосов
/ 07 января 2012

Вы можете использовать @PersistenceContext для компонента CDI. Это не обязательно должен быть EJB.

Если по какой-то причине вы хотите использовать @Inject, вам придется проделать больше работы. @Inject не знает о EntityManager; он может только вводить другие управляемые бины. К счастью, есть простой обходной путь - используйте метод производителя, который действует как простой батут.

@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 будет RequestScoped, а EntityManagerProducer - ApplicationScoped. Кроме того, entityManager должен быть закрыт.

...