Search code examples
hibernatejakarta-eejpapersistencekundera

Composite persistence unit with various JPA versions


We have a problem with multiple persistence units in the same project. We need to use two persistence units in the same time. One "normal" with Hibernate for MySQL and one more with Kundera for Cassandra.

The problem is that unlike Hibernate/MySQL, Kundera/Cassandra seems not to support JPA 2.1.

The persistence XML looked like:

<persistence version="2.1" xmlns="http://xmlns.jcp.org/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/persistence http://xmlns.jcp.org/xml/ns/persistence/persistence_2_1.xsd">
   <persistence-unit name="pu-mysql" transaction-type="JTA">
      <provider>org.hibernate.ejb.HibernatePersistence</provider>
      <jta-data-source>java:/datasrc</jta-data-source>
      <class>com.blah.Contact</class>
      <exclude-unlisted-classes>false</exclude-unlisted-classes>
      <properties>
         <property name="hibernate.show_sql" value="false"/>
         <property name="hibernate.dialect" value="org.hibernate.dialect.MySQLDialect"/>
      </properties>
   </persistence-unit>
   <persistence-unit name="cassandra-pu">
      <provider>com.impetus.kundera.KunderaPersistence</provider>
      <class>com.blah.nosql.PostLogNosql</class>
      <exclude-unlisted-classes>true</exclude-unlisted-classes>
      <properties>
         <property name="kundera.nodes" value="localhost"/>
         <property name="kundera.port" value="9042"/>
         <property name="kundera.keyspace" value="keyspace_name"/>
         <property name="kundera.dialect" value="cassandra"/>
         <property name="kundera.ddl.auto.prepare" value="validate"/>
         <property name="kundera.client.lookup.class" value="com.impetus.kundera.client.cassandra.dsdriver.DSClientFactory"/>
         <property name="kundera.cache.provider.class" value="com.impetus.kundera.cache.ehcache.EhCacheProvider"/>
         <property name="kundera.annotations.scan.package" value="com.blah.nosql"/>
         <property name="jboss.as.jpa.managed" value="false"/>
      </properties>
   </persistence-unit>
</persistence>

This didn't work. System didn't see Kundera part of the file as Kundera does not support JPA 2.1. We were getting org.hibernate.HibernateException: Missing column: time_key in keyspace_name.ourtable error.

This was solved by changing the persistence header to version 2.0. The header then looks like the following:

<persistence xmlns="http://xmlns.jcp.org/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="2.0" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/persistence http://xmlns.jcp.org/xml/ns/persistence/persistence_2_0.xsd">

...and everything works like a charm. So far so good.

Now, the question is what happens to Hibernate/MySQL as a JPA 2.1 compliant. Are still all its JPA 2.1 specific features available or will they be limited just to a subset relevant to JPA 2.0?

And if the latter, how could I use Hibernate/MySQL as JPA 2.1 and Kundera/Cassandra as JPA 2.0 in the same time?

The application server used is Wildfly 8 and Wildfly 9. Many thanks.


Solution

  • You have one JPA API jar in the CLASSPATH, so will get problems either way. If you try with JPA 2.0 then you are likely to get AbstractMethodError and the like with Hibernate, and vice-versa with JPA 2.1 and Kundera. You have the option of using something like DataNucleus with Cassandra for JPA 2.1 (and it also does RDBMS FWIW). The persistence.xml header is the least of your problems ... 2.0 is adequate since nothing changed in that in JPA 2.1