superbAfterSemperPhi
superbAfterSemperPhi

Reputation: 1292

Hibernate ClassCastException org.hibernate.type.SerializableType cannot be cast to org.hibernate.type.VersionType

I have an odd exception appearing when I try to run a unit test. Here is the stack trace:

javax.persistence.PersistenceException: [PersistenceUnit: testPU] Unable to build Hibernate SessionFactory
    at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.persistenceException(EntityManagerFactoryBuilderImpl.java:1249)
    at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.access$600(EntityManagerFactoryBuilderImpl.java:120)
     ... more
Caused by: org.hibernate.MappingException: Could not instantiate persister org.hibernate.persister.entity.SingleTableEntityPersister
    at org.hibernate.persister.internal.PersisterFactoryImpl.create(PersisterFactoryImpl.java:174)
    at org.hibernate.persister.internal.PersisterFactoryImpl.createEntityPersister(PersisterFactoryImpl.java:135)
    at org.hibernate.internal.SessionFactoryImpl.<init>(SessionFactoryImpl.java:401)
    at org.hibernate.cfg.Configuration.buildSessionFactory(Configuration.java:1859)
    at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl$4.perform(EntityManagerFactoryBuilderImpl.java:857)
    ... 39 more
Caused by: java.lang.ClassCastException: org.hibernate.type.SerializableType cannot be cast to org.hibernate.type.VersionType
    at org.hibernate.tuple.PropertyFactory.buildVersionProperty(PropertyFactory.java:181)
    at org.hibernate.tuple.entity.EntityMetamodel.<init>(EntityMetamodel.java:218)
    at org.hibernate.persister.entity.AbstractEntityPersister.<init>(AbstractEntityPersister.java:520)
    at org.hibernate.persister.entity.SingleTableEntityPersister.<init>(SingleTableEntityPersister.java:148)
    at sun.reflect.GeneratedConstructorAccessor29.newInstance(Unknown Source)
    at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
    at java.lang.reflect.Constructor.newInstance(Constructor.java:422)
    at org.hibernate.persister.internal.PersisterFactoryImpl.create(PersisterFactoryImpl.java:163)
    ... 43 more

Here are the libraries and frameworks that I'm using:

  1. JPA 2.0
  2. org.hibernate:hibernate-entitymanager:4.3.5.Final
  3. com.h2database:h2:1.4.188
  4. junit:junit:4.11
  5. Intellij IDE (I'm just running the test here)
  6. org.hibernate:hibernate-envers:4.3.5.Final

Well, I bet anyone who looks at this wants to see the persistense.xml file so here it is:

<?xml version="1.0" encoding="UTF-8"?>
<persistence xmlns="http://java.sun.com/xml/ns/persistence" version="2.0">
    <persistence-unit name="testPU" transaction-type="RESOURCE_LOCAL">
        <provider>org.hibernate.jpa.HibernatePersistenceProvider</provider>
        <exclude-unlisted-classes>true</exclude-unlisted-classes>

There are many classes here so I've cut them out to keep things readable

        <properties>
            <property name="javax.persistence.jdbc.driver" value="org.h2.Driver" />
            <property name="javax.persistence.jdbc.url" value="jdbc:h2:mem:test;MODE=PostgreSQL;INIT=create schema if not exists test;DB_CLOSE_DELAY=-1" />
            <property name="javax.persistence.jdbc.user" value="sa" />
            <property name="javax.persistence.jdbc.password" value="" />
            <property name="hbm2ddl.auto" value="create" />
            <property name="hibernate.dialect" value="org.hibernate.dialect.PostgreSQL9Dialect"/>
            <property name="hibernate.show_sql" value="false"/>
        </properties>
    </persistence-unit>
</persistence>

The unit test is basic. It just finds a record by a value. Here is the code:

@Test
  public void testFindByNaturalKeyReturnsBusinessUnit() {
    final BusinessUnit businessUnit = mock(BusinessUnit.class);
    assertThat(businessUnitDao.findByNaturalKey(businessUnit.getNaturalKey()).getId(), is(businessUnit.getId()));
  }

Finally, the entity is really complex. I'm not sure if posting the code is going to help. I guess that there is a relationship at fault in the entity so I'm looking into that.

Upvotes: 0

Views: 4162

Answers (1)

superbAfterSemperPhi
superbAfterSemperPhi

Reputation: 1292

OK, there is an answer. The entity class used JodaTime for some of the fields. This required the persistence.xml file to have some additional properties set.

Example of the JodaTime fields:

@javax.persistence.Column(name = "active_date")
private org.joda.time.DateTime activeDate;

Finally, the fixed persistence.xml file:

<?xml version="1.0" encoding="UTF-8"?>
<persistence xmlns="http://java.sun.com/xml/ns/persistence" version="2.0">
    <persistence-unit name="testPU" transaction-type="RESOURCE_LOCAL">
        <provider>org.hibernate.jpa.HibernatePersistenceProvider</provider>
        <exclude-unlisted-classes>true</exclude-unlisted-classes>

There are many classes here so I've cut them out to keep things readable

        <properties>
            <property name="javax.persistence.jdbc.driver" value="org.h2.Driver" />
            <property name="javax.persistence.jdbc.url" value="jdbc:h2:mem:test;MODE=PostgreSQL;INIT=create schema if not exists test;DB_CLOSE_DELAY=-1" />
            <property name="javax.persistence.jdbc.user" value="sa" />
            <property name="javax.persistence.jdbc.password" value="" />
            <property name="hbm2ddl.auto" value="create" />
            <property name="hibernate.dialect" value="org.hibernate.dialect.PostgreSQL9Dialect"/>
            <property name="hibernate.show_sql" value="false"/>
            <property name="jadira.usertype.autoRegisterUserTypes" value="true"/>
            <property name="jadira.usertype.databaseZone" value="jvm"/>
            <property name="jadira.usertype.javaZone" value="jvm"/>
        </properties>
    </persistence-unit>
</persistence>

Upvotes: 1

Related Questions