【问题标题】:Configuration to be able to @Inject EntityManager in Seam 3能够在 Seam 3 中 @Inject EntityManager 的配置
【发布时间】:2012-01-06 19:11:55
【问题描述】:

在我的项目中,我使用 Seam 3,但在注入带有 @Inject 注释的 EntityManager 时遇到问题。我很确定有某种配置可以确保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" />

&lt;components&gt; 标签内。 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。在@Inject 注释中也没有属性unitName 来指定持久性单元。

所以请帮助我配置我的项目,以便我可以使用@InjectEntityManager,如网络上的许多示例所示。

我使用Postgres 数据库和JBoss AS 7

编辑:添加示例。我不在Entity 类中使用EntityManager

@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]" 的警告

如果我在一些标记为Entity 的bean 上使用@Inject@Inject 可以正常工作。

【问题讨论】:

  • 你有什么问题?如果在同一个persistence.xml 中有多个持久性单元,则只需在注释中使用鉴别器。因为它是你只有一个,这将是默认的。确保您的 persistence.xml 与您的 DAO 和实体类位于同一模块 (JAR) 中。
  • @Perception 请看我编辑的帖子,并给我一些鉴别器的例子。
  • Maistora - 您不需要鉴别器注释,您的 persistence.xml 中只有一个 PU。但是根据您添加的错误消息,我很确定 Eclipse 没有找到您的 JBoss JEE 实现文件。如果您使用的是 Maven,那么您需要将 jboss-javaee-web-6.0 依赖项添加到您的 POM。如果您正在使用其他构建工具,则需要手动查找 JAR 并将其添加到项目类路径中。
  • 如果消息是困扰你的问题,我必须说我成功地在一些 bean 上使用了 [et]Inject。例如@Inject private UserBean userBean;其中 UserBean 被标记为实体。

标签: java configuration persistence cdi seam3


【解决方案1】:

您可以在 CDI bean 上使用 @PersistenceContext。它不一定是 EJB。

如果出于某种原因你想使用@Inject,你必须做更多的工作。 @Inject 不知道 EntityManager;它只能注入其他托管 bean。令人高兴的是,有一个简单的解决方法 - 使用充当简单蹦床的生产者方法。

@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 必须关闭。

【讨论】:

  • 太好了 :) 谢谢,但是当我想使用 entityManager.persist(MyObject) 并出现此错误时: javax.persistence.TransactionRequiredException: Transaction is required to perform this operation (要么使用事务或扩展持久性上下文)
  • 所以我添加了 PersistenceContext(type=PersistenceContextType.EXTENDED) 但什么也没发生。我读到这意味着我应该自己关心交易。有没有办法让容器来管理事务?
  • 不怕。 EJB 获取事务; CDI bean 没有。 Seam 可能对此有所帮助,但我对 Seam 了解不多。在普通的 EE 中,您必须自己管理事务。您的选项有(a)通过 bean 中的 UserTransaction 显式管理事务,(b)添加过滤器并将整个请求周期包装在事务中,以及(c)编写管理事务的 CDI 拦截器(请参阅smokeandice.blogspot.com/2009/12/… - 这个真的很酷!)。
  • @TomAnderson 因为EntityManager 实例不是线程安全的,所以EntityManagerProducer 不应该是@RequestScoped 而不是@ApplicationScoped?甚至会话或对话似乎也很危险,因为同一个会话可能有多个并行请求。
  • @Brian:好问题。我没有想到这一点。我知道 CDI 使用范围感知代理来安全地处理将 bean 注入更广泛范围的其他 bean(请求进入会话等)。这适用于这里吗?或者更确切地说,这是否适用于@PersistenceContext 注入EntityManager 的点?如果不是,那么我写的肯定是错误的,EntityManagerProducer 应该是请求范围的。
猜你喜欢
  • 2012-01-11
  • 2012-01-03
  • 2021-03-28
  • 1970-01-01
  • 1970-01-01
  • 2013-01-08
  • 2012-01-04
  • 2012-06-03
  • 1970-01-01
相关资源
最近更新 更多