Dear Hibernate Team,
i am trying to migrate my JavaEE-Web-Application. The current version runs perfectly with Hibernate 4.2.15.Final and JPA 2.0 (using org.hibernate.*ejb*.HibernatePersistence, PostgreSQL 10, JavaEE 7, Glassfish 3.1.2). However, the migrating to Hibernate 5.3.0.CR1 (same for 5.2.X versions) and JPA 2.1 (using org.hibernate.*jpa*.HibernatePersistenceProvider, PostgreSQL 10, JavaEE 8, Glassfish 5) got stucked by mapping problems between Java-Enums and SQL. It looks like that there is a problem with the mapping of the annotation *@Enumerated(EnumType.STRING)*. Hibernates tries to map an enum attribute with that annotation to a varbinary column. I also tried to add additional org.hibernate.type annotations without any success.
So i decided to drill down the problem and created the following small test case which leads me to the conclusion that there must a bug in Hibernate at least for the combination of versions/configurations i have used together (see below together with the explanations what i tried so far).
Any help is highly appreciated. Thanks in advance.
{code:java} /****** Enum ********************/ public enum EnumTest { SPECIAL, VACATION; } /******* Entity Class **********/ import java.io.Serializable; import javax.persistence.Entity; import javax.persistence.EnumType; import javax.persistence.Enumerated; import javax.persistence.GeneratedValue; import javax.persistence.GenerationType; import javax.persistence.Id;
@Entity public class TestEnum implements Serializable {
static final long serialVersionUID = 1L;
@Id @GeneratedValue(strategy = GenerationType.IDENTITY) protected long id;
@Enumerated(EnumType.STRING) private EnumTest type = EnumTest.VACATION;
public TestEnum() { }
public long getId() {return id;}
public EnumTest getType() {return type;}
public void setId(long id) {this.id = id;}
public void setType(EnumTest type) {this.type = type;} }
/**** persistence.xml *****/ <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="testenumerate" transaction-type="JTA"> <provider>org.hibernate.jpa.HibernatePersistenceProvider</provider> <jta-data-source>jdbc/datasource</jta-data-source> <validation-mode>NONE</validation-mode> <properties> <property name="hibernate.transaction.jta.platform" value="org.hibernate.service.jta.platform.internal.SunOneJtaPlatform" /> <property name="hibernate.enable_lazy_load_no_trans" value="true" /> <!-- Fixes "failed to lazily initialize a collection of role" exception --> <property name="hibernate.cache.provider_class" value="org.hibernate.cache.HashtableCacheProvider" /> <property name="hibernate.id.new_generator_mappings" value="false" /> <property name="hibernate.hbm2ddl.auto" value="update" /> </properties> </persistence-unit> </persistence>
/***** relevant dependencies in pom.xml ******/ <dependencies> <dependency> <groupId>javax</groupId> <artifactId>javaee-api</artifactId> <version>8.0</version> </dependency> <dependency> <groupId>org.hibernate</groupId> <artifactId>hibernate-core</artifactId> <version>5.3.0.CR1</version> </dependency> <dependency> <groupId>org.hibernate.validator</groupId> <artifactId>hibernate-validator</artifactId> <version>6.0.8.Final</version> </dependency> ... <dependencies> ... <build> <resources> <resource> <directory>src/main/resources</directory> </resource> </resources> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <configuration> <source>1.8</source> <target>1.8</target> </configuration> </plugin> </plugins> </build>
/********* Build based on following Java version ***/ java version "1.8.0_161" Java(TM) SE Runtime Environment (build 1.8.0_161-b12) Java HotSpot(TM) 64-Bit Server VM (build 25.161-b12, mixed mode) {code}
Hibernate creates the following table for the above Class TestEnum:
{code:java} CREATE TABLE testenum ( id bigint NOT NULL DEFAULT nextval('testenum_id_seq'::regclass), type * bytea * , CONSTRAINT testenum_pkey PRIMARY KEY (id) ) {code}
1) That is, the annotation @Enumerated(EnumType.STRING) seems to be ignored. Instead of mapping to *varchar*, Hibernate maps the attribute to *varbinary* (in postgres to bytea).
2) Then, I was able to create a row in that table via my Web application. However reading the table, i.e. mapping it back from SQL back to Java via Hibernate failed with the following exception.
{code:java} Caused by: java.lang.IllegalStateException: This web container has not yet been started at org.glassfish.web.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1513) at org.glassfish.web.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1471) at java.lang.Class.forName0(Native Method) at java.lang.Class.forName(Class.java:348) at org.hibernate.internal.util.SerializationHelper$CustomObjectInputStream.resolveClass(SerializationHelper.java:324) at java.io.ObjectInputStream.readNonProxyDesc(ObjectInputStream.java:1859) at java.io.ObjectInputStream.readClassDesc(ObjectInputStream.java:1745) at java.io.ObjectInputStream.readEnum(ObjectInputStream.java:1985) at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1564) at java.io.ObjectInputStream.readObject(ObjectInputStream.java:427) at org.hibernate.internal.util.SerializationHelper.doDeserialize(SerializationHelper.java:225) at org.hibernate.internal.util.SerializationHelper.deserialize(SerializationHelper.java:287) at org.hibernate.type.descriptor.java.SerializableTypeDescriptor.fromBytes(SerializableTypeDescriptor.java:139) at org.hibernate.type.descriptor.java.SerializableTypeDescriptor.wrap(SerializableTypeDescriptor.java:114) at org.hibernate.type.descriptor.java.SerializableTypeDescriptor.wrap(SerializableTypeDescriptor.java:28) at org.hibernate.type.descriptor.sql.VarbinaryTypeDescriptor$2.doExtract(VarbinaryTypeDescriptor.java:60) at org.hibernate.type.descriptor.sql.BasicExtractor.extract(BasicExtractor.java:47) at org.hibernate.type.AbstractStandardBasicType.nullSafeGet(AbstractStandardBasicType.java:261) at org.hibernate.type.AbstractStandardBasicType.nullSafeGet(AbstractStandardBasicType.java:257) at org.hibernate.type.AbstractStandardBasicType.nullSafeGet(AbstractStandardBasicType.java:247) at org.hibernate.type.AbstractStandardBasicType.hydrate(AbstractStandardBasicType.java:333) at org.hibernate.persister.entity.AbstractEntityPersister.hydrate(AbstractEntityPersister.java:2932) at org.hibernate.loader.Loader.loadFromResultSet(Loader.java:1747) at org.hibernate.loader.Loader.instanceNotYetLoaded(Loader.java:1673) at org.hibernate.loader.Loader.getRow(Loader.java:1562) at org.hibernate.loader.Loader.getRowFromResultSet(Loader.java:732) at org.hibernate.loader.Loader.processResultSet(Loader.java:991) at org.hibernate.loader.Loader.doQuery(Loader.java:949) at org.hibernate.loader.Loader.doQueryAndInitializeNonLazyCollections(Loader.java:341) at org.hibernate.loader.Loader.doList(Loader.java:2692) at org.hibernate.loader.Loader.doList(Loader.java:2675) at org.hibernate.loader.Loader.listIgnoreQueryCache(Loader.java:2507) at org.hibernate.loader.Loader.list(Loader.java:2502) at org.hibernate.loader.hql.QueryLoader.list(QueryLoader.java:504) at org.hibernate.hql.internal.ast.QueryTranslatorImpl.list(QueryTranslatorImpl.java:397) at org.hibernate.engine.query.spi.HQLQueryPlan.performList(HQLQueryPlan.java:221) at org.hibernate.internal.SessionImpl.list(SessionImpl.java:1493) at org.hibernate.query.internal.AbstractProducedQuery.doList(AbstractProducedQuery.java:1534) at org.hibernate.query.internal.AbstractProducedQuery.list(AbstractProducedQuery.java:1502) at org.hibernate.query.Query.getResultList(Query.java:146) at com.sun.enterprise.container.common.impl.QueryWrapper.getResultList(QueryWrapper.java:84) at org.bfabric.component.gui.manager.TestEnumManager.getEntities(TestEnumManager.java:47) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:498) at javax.el.BeanELResolver.getValue(BeanELResolver.java:362) ... 76 more
2018-03-15T16:21:36.692+0100|Warning: StandardWrapperValve[Faces Servlet]: Servlet.service() for servlet Faces Servlet threw exception java.lang.IllegalStateException: This web container has not yet been started at org.glassfish.web.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1513) at org.glassfish.web.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1471) at java.lang.Class.forName0(Native Method) at java.lang.Class.forName(Class.java:348) at org.hibernate.internal.util.SerializationHelper$CustomObjectInputStream.resolveClass(SerializationHelper.java:324) at java.io.ObjectInputStream.readNonProxyDesc(ObjectInputStream.java:1859) at java.io.ObjectInputStream.readClassDesc(ObjectInputStream.java:1745) at java.io.ObjectInputStream.readEnum(ObjectInputStream.java:1985) at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1564) at java.io.ObjectInputStream.readObject(ObjectInputStream.java:427) at org.hibernate.internal.util.SerializationHelper.doDeserialize(SerializationHelper.java:225) at org.hibernate.internal.util.SerializationHelper.deserialize(SerializationHelper.java:287) at org.hibernate.type.descriptor.java.SerializableTypeDescriptor.fromBytes(SerializableTypeDescriptor.java:139) at org.hibernate.type.descriptor.java.SerializableTypeDescriptor.wrap(SerializableTypeDescriptor.java:114) at org.hibernate.type.descriptor.java.SerializableTypeDescriptor.wrap(SerializableTypeDescriptor.java:28) at org.hibernate.type.descriptor.sql.VarbinaryTypeDescriptor$2.doExtract(VarbinaryTypeDescriptor.java:60) at org.hibernate.type.descriptor.sql.BasicExtractor.extract(BasicExtractor.java:47) at org.hibernate.type.AbstractStandardBasicType.nullSafeGet(AbstractStandardBasicType.java:261) at org.hibernate.type.AbstractStandardBasicType.nullSafeGet(AbstractStandardBasicType.java:257) at org.hibernate.type.AbstractStandardBasicType.nullSafeGet(AbstractStandardBasicType.java:247) at org.hibernate.type.AbstractStandardBasicType.hydrate(AbstractStandardBasicType.java:333) at org.hibernate.persister.entity.AbstractEntityPersister.hydrate(AbstractEntityPersister.java:2932) at org.hibernate.loader.Loader.loadFromResultSet(Loader.java:1747) at org.hibernate.loader.Loader.instanceNotYetLoaded(Loader.java:1673) at org.hibernate.loader.Loader.getRow(Loader.java:1562) at org.hibernate.loader.Loader.getRowFromResultSet(Loader.java:732) at org.hibernate.loader.Loader.processResultSet(Loader.java:991) at org.hibernate.loader.Loader.doQuery(Loader.java:949) at org.hibernate.loader.Loader.doQueryAndInitializeNonLazyCollections(Loader.java:341) at org.hibernate.loader.Loader.doList(Loader.java:2692) at org.hibernate.loader.Loader.doList(Loader.java:2675) at org.hibernate.loader.Loader.listIgnoreQueryCache(Loader.java:2507) at org.hibernate.loader.Loader.list(Loader.java:2502) at org.hibernate.loader.hql.QueryLoader.list(QueryLoader.java:504) at org.hibernate.hql.internal.ast.QueryTranslatorImpl.list(QueryTranslatorImpl.java:397) at org.hibernate.engine.query.spi.HQLQueryPlan.performList(HQLQueryPlan.java:221) at org.hibernate.internal.SessionImpl.list(SessionImpl.java:1493) at org.hibernate.query.internal.AbstractProducedQuery.doList(AbstractProducedQuery.java:1534) at org.hibernate.query.internal.AbstractProducedQuery.list(AbstractProducedQuery.java:1502) at org.hibernate.query.Query.getResultList(Query.java:146) at com.sun.enterprise.container.common.impl.QueryWrapper.getResultList(QueryWrapper.java:84) {code}
3) My Next try was to replace the column "type" in the table testenum by a character varying(16) column. The value of the column "type" was changed as needed, too:
{code:java} update testenum set type = 'VACATION'; {code}
Trying to read the table testenum via my Web application now delivered to following exception.
{code:java} Caused by: org.hibernate.type.SerializationException: could not deserialize at org.hibernate.internal.util.SerializationHelper.doDeserialize(SerializationHelper.java:243) at org.hibernate.internal.util.SerializationHelper.deserialize(SerializationHelper.java:287) at org.hibernate.type.descriptor.java.SerializableTypeDescriptor.fromBytes(SerializableTypeDescriptor.java:139) at org.hibernate.type.descriptor.java.SerializableTypeDescriptor.wrap(SerializableTypeDescriptor.java:114) at org.hibernate.type.descriptor.java.SerializableTypeDescriptor.wrap(SerializableTypeDescriptor.java:28) at org.hibernate.type.descriptor.sql.VarbinaryTypeDescriptor$2.doExtract(VarbinaryTypeDescriptor.java:60) at org.hibernate.type.descriptor.sql.BasicExtractor.extract(BasicExtractor.java:47) at org.hibernate.type.AbstractStandardBasicType.nullSafeGet(AbstractStandardBasicType.java:261) at org.hibernate.type.AbstractStandardBasicType.nullSafeGet(AbstractStandardBasicType.java:257) at org.hibernate.type.AbstractStandardBasicType.nullSafeGet(AbstractStandardBasicType.java:247) at org.hibernate.type.AbstractStandardBasicType.hydrate(AbstractStandardBasicType.java:333) at org.hibernate.persister.entity.AbstractEntityPersister.hydrate(AbstractEntityPersister.java:2932) at org.hibernate.loader.Loader.loadFromResultSet(Loader.java:1747) at org.hibernate.loader.Loader.instanceNotYetLoaded(Loader.java:1673) at org.hibernate.loader.Loader.getRow(Loader.java:1562) at org.hibernate.loader.Loader.getRowFromResultSet(Loader.java:732) at org.hibernate.loader.Loader.processResultSet(Loader.java:991) at org.hibernate.loader.Loader.doQuery(Loader.java:949) at org.hibernate.loader.Loader.doQueryAndInitializeNonLazyCollections(Loader.java:341) at org.hibernate.loader.Loader.doList(Loader.java:2692) at org.hibernate.loader.Loader.doList(Loader.java:2675) at org.hibernate.loader.Loader.listIgnoreQueryCache(Loader.java:2507) at org.hibernate.loader.Loader.list(Loader.java:2502) at org.hibernate.loader.hql.QueryLoader.list(QueryLoader.java:504) at org.hibernate.hql.internal.ast.QueryTranslatorImpl.list(QueryTranslatorImpl.java:397) at org.hibernate.engine.query.spi.HQLQueryPlan.performList(HQLQueryPlan.java:221) at org.hibernate.internal.SessionImpl.list(SessionImpl.java:1493) at org.hibernate.query.internal.AbstractProducedQuery.doList(AbstractProducedQuery.java:1534) at org.hibernate.query.internal.AbstractProducedQuery.list(AbstractProducedQuery.java:1502) ... 83 more Caused by: java.io.StreamCorruptedException: invalid stream header: 56414341 at java.io.ObjectInputStream.readStreamHeader(ObjectInputStream.java:862) at java.io.ObjectInputStream.<init>(ObjectInputStream.java:354) at org.hibernate.internal.util.SerializationHelper$CustomObjectInputStream.<init>(SerializationHelper.java:309) at org.hibernate.internal.util.SerializationHelper$CustomObjectInputStream.<init>(SerializationHelper.java:299) at org.hibernate.internal.util.SerializationHelper.doDeserialize(SerializationHelper.java:218) ... 111 more
2018-03-15T16:28:23.822+0100|Warning: StandardWrapperValve[Faces Servlet]: Servlet.service() for servlet Faces Servlet threw exception java.io.StreamCorruptedException: invalid stream header: 56414341 at java.io.ObjectInputStream.readStreamHeader(ObjectInputStream.java:862) at java.io.ObjectInputStream.<init>(ObjectInputStream.java:354) at org.hibernate.internal.util.SerializationHelper$CustomObjectInputStream.<init>(SerializationHelper.java:309) at org.hibernate.internal.util.SerializationHelper$CustomObjectInputStream.<init>(SerializationHelper.java:299) at org.hibernate.internal.util.SerializationHelper.doDeserialize(SerializationHelper.java:218) at org.hibernate.internal.util.SerializationHelper.deserialize(SerializationHelper.java:287) at org.hibernate.type.descriptor.java.SerializableTypeDescriptor.fromBytes(SerializableTypeDescriptor.java:139) at org.hibernate.type.descriptor.java.SerializableTypeDescriptor.wrap(SerializableTypeDescriptor.java:114) at org.hibernate.type.descriptor.java.SerializableTypeDescriptor.wrap(SerializableTypeDescriptor.java:28) at org.hibernate.type.descriptor.sql.VarbinaryTypeDescriptor$2.doExtract(VarbinaryTypeDescriptor.java:60) at org.hibernate.type.descriptor.sql.BasicExtractor.extract(BasicExtractor.java:47) at org.hibernate.type.AbstractStandardBasicType.nullSafeGet(AbstractStandardBasicType.java:261) at org.hibernate.type.AbstractStandardBasicType.nullSafeGet(AbstractStandardBasicType.java:257) at org.hibernate.type.AbstractStandardBasicType.nullSafeGet(AbstractStandardBasicType.java:247) at org.hibernate.type.AbstractStandardBasicType.hydrate(AbstractStandardBasicType.java:333) at org.hibernate.persister.entity.AbstractEntityPersister.hydrate(AbstractEntityPersister.java:2932) at org.hibernate.loader.Loader.loadFromResultSet(Loader.java:1747) at org.hibernate.loader.Loader.instanceNotYetLoaded(Loader.java:1673) at org.hibernate.loader.Loader.getRow(Loader.java:1562) at org.hibernate.loader.Loader.getRowFromResultSet(Loader.java:732) at org.hibernate.loader.Loader.processResultSet(Loader.java:991) at org.hibernate.loader.Loader.doQuery(Loader.java:949) at org.hibernate.loader.Loader.doQueryAndInitializeNonLazyCollections(Loader.java:341) at org.hibernate.loader.Loader.doList(Loader.java:2692) at org.hibernate.loader.Loader.doList(Loader.java:2675) at org.hibernate.loader.Loader.listIgnoreQueryCache(Loader.java:2507) at org.hibernate.loader.Loader.list(Loader.java:2502) at org.hibernate.loader.hql.QueryLoader.list(QueryLoader.java:504) at org.hibernate.hql.internal.ast.QueryTranslatorImpl.list(QueryTranslatorImpl.java:397) at org.hibernate.engine.query.spi.HQLQueryPlan.performList(HQLQueryPlan.java:221) at org.hibernate.internal.SessionImpl.list(SessionImpl.java:1493) at org.hibernate.query.internal.AbstractProducedQuery.doList(AbstractProducedQuery.java:1534) at org.hibernate.query.internal.AbstractProducedQuery.list(AbstractProducedQuery.java:1502) at org.hibernate.query.Query.getResultList(Query.java:146) at com.sun.enterprise.container.common.impl.QueryWrapper.getResultList(QueryWrapper.java:84) {code} |
|