2012-01-06 63 views
3

在我的項目中,我使用了Seam 3,並且我注意到注入了EntityManager@Inject註釋。我很確定有一些配置可以確保EnityManager知道要使用哪個PersistenceUnit。例如用EJB可以鍵入:配置能夠在@Seam中注入EntityManager 3

@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> 

我已經加入了閱讀接縫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@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我從EclipseNo bean is eligible for injection to the injection point [JSR-299 §5.2.1]

警告,如果我上了些豆子,被標記爲Entity@Inject工作正常使用@Inject

+0

你有什麼問題?如果在同一個persistence.xml中有多個持久性單元,則只需在註釋中使用鑑別符。因爲它只是一個默認值。確保你的persistence.xml和你的DAO和Entity類在同一個模塊(JAR)中。 – Perception 2012-01-06 19:24:43

+0

@Perception請看看我編輯的帖子,並給我一些鑑別器的例子。 – nyxz 2012-01-06 20:35:14

+0

Maistora - 你不需要鑑別註釋,你只有一個PU在你的persistence.xml。但基於您添加的錯誤消息,我很確定Eclipse沒有找到您的JBoss JEE實現文件。如果您使用的是Maven,那麼您需要將jboss-javaee-web-6.0依賴項添加到您的POM中。如果您使用其他構建工具,那麼您需要手動查找並添加JAR到您的項目類路徑。 – Perception 2012-01-06 20:49:22

回答

5

您可以在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必須關閉。

+0

這是很不錯的:)謝謝,但是當我想用entityManager.persist(myObject的),並且此錯誤出現:javax.persistence.TransactionRequiredException:事務需要執行此操作(無論是使用事務或擴展的持久化上下文) – nyxz 2012-01-07 13:43:30

+0

所以我添加了PersistenceContext(type = PersistenceContextType.EXTENDED),但沒有發生任何事情。我讀到這意味着我應該自己關心交易。有沒有辦法讓容器管理交易? – nyxz 2012-01-07 13:45:57

+1

不怕。 EJB獲取事務; CDI豆沒有。 Seam可能對此有所幫助,但我對Seam瞭解不多。在簡單的EE中,您必須自己管理事務。您的選項有(一)在bean通過UserTransaction的管理事務明確,(B)添加過濾器和整個包住請求週期在一個事務中,以及(c)編寫管理事務的CDI攔截器(請參見http:// smokeandice .blogspot.com/2009/12/cdi-and-declarative-transactions.html - 這真的很酷!)。 – 2012-01-07 22:20:45