How to change Persistence Unit dynamically?

2.9k Views Asked by At

I have a Spring MVC + Hibernate + JPA app. Also have 4 different Schemas in my db with similar tables. (for different companies) .

Now when I'm using my Hibernate app, can i switch Persistence Unit so that I can use same the form (with the same content) to save data in all four Schemas?

I'm aware that i can switch persistence unit at run time, but i want to be able to use the already loaded forms to save data to all four Schemas by changing the persistence unit.

2

There are 2 best solutions below

0
On

I am not sure to understand your problem: of course you can change the PersistentUnit used at runtime with the Persistence#createEntityManagerFactory(String persistenceUnitName) method.

But if you want to

save data to all four Schemas

Then you should repeat your operation (persist I guess) four times (for example in a private method taking the persistence unit name as parameter).

You could introduce a form cache if you want to reuse the already loaded forms, but this is a software architecture question.

As suggested in the Java EE 5 tutorial, on a software design point of view, having a form depending directly on the JPA layer is not a best practice. The other answer suggests it: a DAO could be the solution. All is about your DAOs lifecyle.

The Core JEE patterns book suggests it (the online reference only mentions briefly the topic, the printed book is better): associating DAOs with a Factory pattern is a good idea. You could recycle the EntityManagerFactory or anything you wish.

0
On

I had similar problem some time ago. I had 2 identical schemas - application had to persist to first or second depending on some logic. It was pure Hibernate, but talking in terms of JPA I will suggest to have 4 persistence units defined in your persistence.xml:

persistence.xml

<persistence-unit name="PU1">
  ...
</persistence-unit>

<persistence-unit name="PU2">
  ...
</persistence-unit>

[...]

and DAO class that has injected EntityManager proxies - each for different PU:

@Repository
public class MyDaoImpl implements MyDao {

    @PersistenceContext(unitName = "PU1") 
    private EntityManager em1;

    @PersistenceContext(unitName = "PU2") 
    private EntityManager em2;

    ...

    public void saveToPU1(MyEntity e) {
        em1.persist(e);
    }
    public void saveToPU2(MyEntity e) {
        em2.persist(e);
    }
    ...

}

Of course em1 annotated with @PersistenceContext(unitName="PU1") is Spring's proxy to Hibernate session and becomes open and bound with current thread only if that thread tries to use it.