2015-11-18 67 views
2
修改的unitName

我使用JPA 2.1和我的財產以後這樣如何動態地在@PersistenceContext

public class EntityManagerProducer { 
    @Produces 
    @PersistenceContext(unitName="first_PU") 
    private EntityManager em; 
    ... 

如何動態修改unitName@PersistenceContext(unitName = "somer_PU")使用於其他實體管理器?這可能嗎?

非常重要更新

我有一個部署的應用程序中,persistence.xml這個樣子的:

<persistence-unit name="db1" transaction-type="JTA"> 
<jta-data-source>java:/jboss/datasources/PostgresDS</jta-data-source> 
<properties> 
    <property name="hibernate.hbm2ddl.auto" value="update"/> 
    <property name="hibernate.show_sql" value="true"/> 
    <property name="hibernate.format_sql" value="true"/> 
    <property name="hibernate.dialect" value="org.hibernate.dialect.PostgreSQLDialect"/> 
    <property name="hibernate.cache.use_second_level_cache" value="false"/> 
    <property name="hibernate.jdbc.batch_size" value="50"/> 
    <property name="hibernate.jdbc.batch_versioned_data" value="true"/> 
    <property name="hibernate.order_inserts" value="true"/> 
    <property name="hibernate.order_updates" value="true"/> 
    <property name="hibernate.generate_statistics" value="true"/> 
    <property name="javax.persistence.schema-generation.database.action" value="drop-and-create"/> 
    <property name="jboss.entity.manager.jndi.name" value="java:app/entitymanager/db1"/> 
    <property name="jboss.entity.manager.factory.jndi.name" value="java:app/entitymanagerfactory/db1"/> 
</properties> 

在運行時,可以修改persistence.xml並添加另一個持久性單元,但我需要通過傳遞持久化單元的名稱或其他方法來獲取我需要的entitymanager,然後使用它爲我想要的。然後我可以提供持久單元的另一個名稱並獲得一個不同的實體管理器。當然我希望交易過程仍然是集裝箱管理

+0

對不起,但我仍然看不到在運行時更改持久單元名稱的目的。你可以解釋嗎?你的應用程序是否需要與多個不同的數據庫交談?你是什​​麼意思*在運行時,可以修改persistence.xml ... *? –

+0

我的意思是,當應用程序部署在服務器上時,它可以添加更多的持久性單元。是的,我需要我的應用程序可以與多個不同的數據庫交談。 –

+0

但是僅僅動態定義DataSource還不夠?說實話,你可以在你的java代碼中連接到任何數據庫:打開一個連接並執行所需的SQL語句(不使用'EntityManager')。 順便說一句:你的應用程序與固定數字對話的數據庫數量是多少? –

回答

4

相信我,您不想修改現有PersistenceContext內部的unitName。我幾乎可以肯定,你想要達到的目標是第二個EntityManager指向一個不同的數據庫,對吧?

然後以自然的方式去爲:

public class SomeClass { 

    @PersistenceContext(unitName = "first_PU") 
    EntityManager firstEntityManager; 

    @PersistenceContext(unitName = "somer_PU") 
    EntityManager secondEntityManager; 

    // ... 
} 

個人意見

  1. 也請注意,使用EJB時​​,您不必創建Producer方法對於EntityManager來說,輸入@PersistenceContext(...)就足夠了。

  2. 也是繼極力勸阻:

    @Produces 
    @PersistenceContext(unitName="first_PU") 
    private EntityManager em; 
    

    因爲默認範圍是@Dependent。更好的是@RequestScoped@TransactionScoped

  3. 而不是硬編碼的單位名稱,你可以使用CDI和註釋預選賽:

    @Inject 
    private @FirstDB EntityManager firstEntityManager; 
    
    @Inject 
    private @SecondDB EntityManager secondEntityManager; 
    

    但你需要有:

    @Produces 
    @RequestScoped // or other 
    @FirstDB 
    public EntityManager createEntityManagerA() { 
        return firstEmf.createEntityManager(); 
    } 
    
    @Produces 
    @RequestScoped // or other 
    @SecondDB 
    public EntityManager createEntityManagerB() { 
        return secondEmf.createEntityManager(); 
    } 
    

了很多有用的信息有關CDI和生產多個EntityManagers,你可以找到here

+1

您好,G. Demecki,您的回答和您給我的鏈接非常有幫助,他們幫助我澄清了一些疑問。但不幸的是,我的情況稍微複雜一點,因爲我不知道在運行時會使用什麼持久性單元,我不知道有多少可能有,所以我可以硬編碼這些Entitymanagers。我稍微更新我的問題,如果需要更多信息,請告訴我。 –

0

這是不可能的。如果您需要動態持久單元名稱,則需要完全避免EE集成,並直接使用javax.persistence.Persistence類,但我不建議這樣做。或者,您可以爲所有持久性單元注入EntityManager/Factory,然後使用switch語句或類似語句選擇正確的一個。

+0

你可以建議一個使用你提出的替代方案的例子嗎? –