Randy Hector
Randy Hector

Reputation: 99

how to dynamically modifying unitName in @PersistenceContext

I'm using JPA 2.1 and I have somthing like this

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

How can I dynamically modify the unitName in @PersistenceContext(unitName = "somer_PU") to use an other entity manager? Is this possible?

VERY IMPORTANT UPDATE

I have a deployed application,the persistence.xml look like this:

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

At runtime, could modify the persistence.xml and add another persistence unit but I need a way to get the entitymanager that I need by passing the name of the persistence unit or something, and then using it for what I want. Then I could provide another name of persistence unit and get a different entitymanager. Of course I would like that the transaction process still be container-managed.

Upvotes: 4

Views: 13437

Answers (2)

G. Demecki
G. Demecki

Reputation: 10596

Believe me, you don't want to modify the unitName inside existing PersistenceContext. I'm almost sure that all you want to achieve is to have a second EntityManager pointing to a different database, right?

Then a natural way to go is:

public class SomeClass {

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

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

    // ...
}

Personal advices

  1. Please also notice that when using EJB, you don't have to create Producer methods for the EntityManager, as typing @PersistenceContext(...) is enough.

  2. Also following is highly discouraged:

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

    because default scope is @Dependent. Much better would be @RequestScoped or @TransactionScoped.

  3. Instead of hard-coded unit names you can use CDI and annotations qualifiers:

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

    But then you need to have:

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

A lot of useful information about CDI and producing multiple EntityManagers you can find here.

Upvotes: 8

Brett Kail
Brett Kail

Reputation: 33956

This is not possible. If you need a dynamic persistence unit name, you would need to avoid EE integration altogether and use the javax.persistence.Persistence class directly, but I would not recommend doing that. As an alternative, you could inject EntityManager/Factory for all persistence units, and then select the correct one using a switch statement or similar.

Upvotes: 0

Related Questions