Question

I have a webapp using JPA provided by Hibernate and Tomcat. I have no DI framework, no Spring, no Guice, no full Java EE app server.

I need JPA to connect to two different databases. I connect to the first database like this:

EntityManagerFactory emf = Persistence.createEntityManagerFactory("mydb");
[...]
EntityManager em = emf.createEntityManager();

and I have the "mydb" persistence unit declared in persistence.xml and linked through JNDI to its resource declared in context.xml. Till here everithing works.

Now I need to connect to another database. I've added it to persistence.xml and context.xml and named the persistence unit "mydb2". Now I assume I can use it like this:

EntityManagerFactory emf2 = Persistence.createEntityManagerFactory("mydb2");
EntityManager em2 = emf2.createEntityManager();

Hibernate is configured to validate classes and tables on both databases with

<property name="hibernate.archive.autodetection" value="class, hbm"/>
<property name="hibernate.hbm2ddl.auto" value="validate"/>

in persistence.xml. However when I run/debug the webapp, Hibernate tries to validate @Entity classes that belong to mydb2 on mydb, and it obviously fails. Now the fun part is that if I set the Hibernate validation property to "none", my application does work correctly and connects to the correct db as needed...

Is there a way to have Hibernate validate only the classes/tables belonging to their respective database?

EDIT: While it's possible to specify a catalog name in @Table annotations, in my case it's not a good solution, because I have more than one instance of this webapp in production and each instance connects to a different pair of databases. Being forced to touch the source code just before going into production is bad.

Was it helpful?

Solution

If you use the @javax.persistence.Table annotation, you can use the catalog parameter to discriminate between databases.

EDIT: Try defining separate hibernate-cfg.xml files (call them db1-hibernate-cfg.xml and db2-hibernate-cfg.xml) and in the xml element use the element to list out the entites that correspond to that factory. You may also define these in the orm.xml that corresponds to JPA.

Then in your spring configuration explicitly define which hibernate-cfg (or orm.xml) maps to which EntityManager:

Example using Spring's LocalContainerEntityManagerFactoryBean:

<bean id="emf" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
    <property name="persistenceUnitManager" ref="pum" />
    <property name="persistenceUnitName" value="my-pu" />
    <property name="jpaProperties">
        <props>
            <prop key="hibernate.ejb.cfgfile">my-hibernate.cfg.xml</prop>
                            ... other configurations
                    </props>
 </bean>

If you go the route of defining separate orm.xml files then in your persistence-unit-manager, define a separate persistence.xml file for each entity manager factory (say db1-persistence.xml and db2 ..). In the persistence.xml file use the element to define the corresponding orm.xml file.

The default location of these files is classpath-relative.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top