'Hibernate 5 migration Issue with Multilevel Joined table Inheritance with Hibernate 5.4 DiscriminatorColumn
I am working on migrating a legacy Hibernate
project from version 4.1
to 5.4
. The code has Multilevel Joined table inheritance using a dedicated DiscriminatorColumn
. The code was working fine in Hibernate 4 but throwing errors in Hibernate 5.
In-Short class hierarchy is like:
And, the code looks like:
First level Super class
@Entity
@Table(name="VideoTag")
@Inheritance(strategy = InheritanceType.JOINED)
@DiscriminatorColumn(name = "VideoTagType", discriminatorType = DiscriminatorType.INTEGER)
@DiscriminatorOptions(force=true)
public abstract class VideoTag implements Cloneable {
@Id
@Column(name = "AdTagId")
private Long adTagId;
@Column(name = "VideoTagType")
@Type(type = "enum_pub_video_tag_type")
private VideoTagType videoTagType;
//Non-important columns
//Accessors
}
Second level classes
Simple sub-class:
@Entity
@DiscriminatorValue(value = "2")
@Table(name = "OutstreamVideoTag")
public class OutStreamVideoTag extends VideoTag implements Cloneable {
//Non-important columns
//Accessors
}
Complex sub-class/Second level super class
@Entity
@DiscriminatorValue(value = "1")
@Table(name = "InStreamVideoTag")
@Inheritance(strategy = InheritanceType.JOINED)
@DiscriminatorColumn(name = "InstreamVideoTagType", discriminatorType = DiscriminatorType.INTEGER)
public abstract class InStreamVideoTag extends VideoTag implements Cloneable {
@Column(name = "InstreamVideoTagType")
@Type(type = "enum_pub_instream_video_tag_type")
private InstreamVideoTagType instreamVideoTagType;
//Non-important columns
//Accessors
}
Last level Sub-classes
@Entity
@DiscriminatorValue(value = "1")
@Table(name = "RegularInStreamVideoTag")
public class RegularInStreamVideoTag extends InStreamVideoTag implements Cloneable {
//Non-important columns
//Accessors
}
@Entity
@DiscriminatorValue(value = "2")
@Table(name = "InAppInstreamVideoTag")
public class InAppInstreamVideoTag extends InStreamVideoTag implements Cloneable {
//Non-important columns
//Accessors
}
Errors
1. Save of RegularInStreamVideoTag entity is throwing the following error:
[DEBUG][SQL,qtp88259764-236] -
insert
into
VideoTag
(PlayerType, VideoTagType, AdTagId)
values
(?, 1, ?)
Hibernate:
insert
into
VideoTag
(PlayerType, VideoTagType, AdTagId)
values
(?, 1, ?)
[DEBUG][SqlExceptionHelper,qtp88259764-236] - could not insert: [com.domain.businessobject.publisher.RegularInStreamVideoTag] [insert into VideoTag (PlayerType, VideoTagType, AdTagId) values (?, 1, ?)]
com.microsoft.sqlserver.jdbc.SQLServerException: The index 3 is out of range.
at com.microsoft.sqlserver.jdbc.SQLServerException.makeFromDriverError(SQLServerException.java:234) ~[mssql-jdbc-9.2.1.jre11.jar:?]
at com.microsoft.sqlserver.jdbc.SQLServerPreparedStatement.setterGetParam(SQLServerPreparedStatement.java:1115) ~[mssql-jdbc-9.2.1.jre11.jar:?]
at com.microsoft.sqlserver.jdbc.SQLServerPreparedStatement.setValue(SQLServerPreparedStatement.java:1129) ~[mssql-jdbc-9.2.1.jre11.jar:?]
at com.microsoft.sqlserver.jdbc.SQLServerPreparedStatement.setLong(SQLServerPreparedStatement.java:1429) ~[mssql-jdbc-9.2.1.jre11.jar:?]
at com.zaxxer.hikari.pool.HikariProxyPreparedStatement.setLong(HikariProxyPreparedStatement.java) ~[HikariCP-3.4.5.jar:?]
at org.hibernate.type.descriptor.sql.BigIntTypeDescriptor$1.doBind(BigIntTypeDescriptor.java:46) ~[hibernate-core-5.4.32.Final.jar:5.4.32.Final]
at org.hibernate.type.descriptor.sql.BasicBinder.bind(BasicBinder.java:73) ~[hibernate-core-5.4.32.Final.jar:5.4.32.Final]
at org.hibernate.type.AbstractStandardBasicType.nullSafeSet(AbstractStandardBasicType.java:276) ~[hibernate-core-5.4.32.Final.jar:5.4.32.Final]
at org.hibernate.type.AbstractStandardBasicType.nullSafeSet(AbstractStandardBasicType.java:271) ~[hibernate-core-5.4.32.Final.jar:5.4.32.Final]
at org.hibernate.persister.entity.AbstractEntityPersister.dehydrateId(AbstractEntityPersister.java:3040) ~[hibernate-core-5.4.32.Final.jar:5.4.32.Final]
at org.hibernate.persister.entity.AbstractEntityPersister.dehydrate(AbstractEntityPersister.java:2998) ~[hibernate-core-5.4.32.Final.jar:5.4.32.Final]
at org.hibernate.persister.entity.AbstractEntityPersister.insert(AbstractEntityPersister.java:3289) ~[hibernate-core-5.4.32.Final.jar:5.4.32.Final]
at org.hibernate.persister.entity.AbstractEntityPersister.insert(AbstractEntityPersister.java:3825) ~[hibernate-core-5.4.32.Final.jar:5.4.32.Final]
at org.hibernate.action.internal.EntityInsertAction.execute(EntityInsertAction.java:107) ~[hibernate-core-5.4.32.Final.jar:5.4.32.Final]
at org.hibernate.engine.spi.ActionQueue.executeActions(ActionQueue.java:604) ~[hibernate-core-5.4.32.Final.jar:5.4.32.Final]
at org.hibernate.engine.spi.ActionQueue.executeInserts(ActionQueue.java:461) ~[hibernate-core-5.4.32.Final.jar:5.4.32.Final]
at org.hibernate.engine.spi.ActionQueue.addInsertAction(ActionQueue.java:258) ~[hibernate-core-5.4.32.Final.jar:5.4.32.Final]
at org.hibernate.engine.spi.ActionQueue.addAction(ActionQueue.java:317) ~[hibernate-core-5.4.32.Final.jar:5.4.32.Final]
at org.hibernate.event.internal.AbstractSaveEventListener.addInsertAction(AbstractSaveEventListener.java:330) ~[hibernate-core-5.4.32.Final.jar:5.4.32.Final]
at org.hibernate.event.internal.AbstractSaveEventListener.performSaveOrReplicate(AbstractSaveEventListener.java:287) ~[hibernate-core-5.4.32.Final.jar:5.4.32.Final]
at org.hibernate.event.internal.AbstractSaveEventListener.performSave(AbstractSaveEventListener.java:193) ~[hibernate-core-5.4.32.Final.jar:5.4.32.Final]
at org.hibernate.event.internal.AbstractSaveEventListener.saveWithGeneratedId(AbstractSaveEventListener.java:123) ~[hibernate-core-5.4.32.Final.jar:5.4.32.Final]
at org.hibernate.event.internal.DefaultSaveOrUpdateEventListener.saveWithGeneratedOrRequestedId(DefaultSaveOrUpdateEventListener.java:194) ~[hibernate-core-5.4.32.Final.jar:5.4.32.Final]
at org.hibernate.event.internal.DefaultSaveOrUpdateEventListener.entityIsTransient(DefaultSaveOrUpdateEventListener.java:179) ~[hibernate-core-5.4.32.Final.jar:5.4.32.Final]
at org.hibernate.event.internal.DefaultSaveOrUpdateEventListener.performSaveOrUpdate(DefaultSaveOrUpdateEventListener.java:100) ~[hibernate-core-5.4.32.Final.jar:5.4.32.Final]
at org.hibernate.event.internal.DefaultSaveOrUpdateEventListener.onSaveOrUpdate(DefaultSaveOrUpdateEventListener.java:75) ~[hibernate-core-5.4.32.Final.jar:5.4.32.Final]
at org.hibernate.event.service.internal.EventListenerGroupImpl.fireEventOnEachListener(EventListenerGroupImpl.java:99) ~[hibernate-core-5.4.32.Final.jar:5.4.32.Final]
at org.hibernate.internal.SessionImpl.fireSaveOrUpdate(SessionImpl.java:616) ~[hibernate-core-5.4.32.Final.jar:5.4.32.Final]
at org.hibernate.internal.SessionImpl.saveOrUpdate(SessionImpl.java:609) ~[hibernate-core-5.4.32.Final.jar:5.4.32.Final]
at org.hibernate.internal.SessionImpl.saveOrUpdate(SessionImpl.java:604) ~[hibernate-core-5.4.32.Final.jar:5.4.32.Final]
at com.domain.api.commons.dao.impl.AdTagDAOImpl.lambda$saveOrUpdateHeaderBiddingInfo$0(AdTagDAOImpl.java:918) ~[open-api-commons-dao-11.0.0.jar:11.0.0]
at java.lang.Iterable.forEach(Iterable.java:75) ~[?:?]
at com.domain.api.commons.dao.impl.AdTagDAOImpl.saveOrUpdateHeaderBiddingInfo(AdTagDAOImpl.java:918) ~[open-api-commons-dao-11.0.0.jar:11.0.0]
at com.domain.api.commons.processor.publisher.impl.AdTagProcessorImpl.saveOrUpdateHeaderBiddingInfo(AdTagProcessorImpl.java:2428) ~[open-api-commons-processor-11.0.0.jar:11.0.0]
at com.domain.publisher.endpoint.AdTagServiceEndpointImpl.createAdTag(AdTagServiceEndpointImpl.java:427) ~[classes/:?]
at com.domain.publisher.endpoint.AdTagServiceEndpointImpl$$FastClassBySpringCGLIB$$9fdcaf7e.invoke(<generated>) ~[classes/:?]
at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:218) ~[spring-core-5.3.8.jar:5.3.8]
at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.invokeJoinpoint(CglibAopProxy.java:779) ~[spring-aop-5.3.8.jar:5.3.8]
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:163) ~[spring-aop-5.3.8.jar:5.3.8]
at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:750) ~[spring-aop-5.3.8.jar:5.3.8]
at org.springframework.transaction.interceptor.TransactionInterceptor$1.proceedWithInvocation(TransactionInterceptor.java:123) ~[spring-tx-5.3.8.jar:5.3.8]
at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:388) ~[spring-tx-5.3.8.jar:5.3.8]
at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:119) ~[spring-tx-5.3.8.jar:5.3.8]
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186) ~[spring-aop-5.3.8.jar:5.3.8]
at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:750) ~[spring-aop-5.3.8.jar:5.3.8]
at org.springframework.transaction.interceptor.TransactionInterceptor$1.proceedWithInvocation(TransactionInterceptor.java:123) ~[spring-tx-5.3.8.jar:5.3.8]
at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:388) ~[spring-tx-5.3.8.jar:5.3.8]
at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:119) ~[spring-tx-5.3.8.jar:5.3.8]
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186) ~[spring-aop-5.3.8.jar:5.3.8]
at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:750) ~[spring-aop-5.3.8.jar:5.3.8]
at org.springframework.transaction.interceptor.TransactionInterceptor$1.proceedWithInvocation(TransactionInterceptor.java:123) ~[spring-tx-5.3.8.jar:5.3.8]
at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:388) ~[spring-tx-5.3.8.jar:5.3.8]
at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:119) ~[spring-tx-5.3.8.jar:5.3.8]
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186) ~[spring-aop-5.3.8.jar:5.3.8]
at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:750) ~[spring-aop-5.3.8.jar:5.3.8]
at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:97) ~[spring-aop-5.3.8.jar:5.3.8]
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186) ~[spring-aop-5.3.8.jar:5.3.8]
at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:750) ~[spring-aop-5.3.8.jar:5.3.8]
at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:692) ~[spring-aop-5.3.8.jar:5.3.8]
at com.domain.publisher.endpoint.AdTagServiceEndpointImpl$$EnhancerBySpringCGLIB$$cca3b878.createAdTag(<generated>) ~[classes/:?]
at jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[?:?]
at jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[?:?]
at jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[?:?]
at java.lang.reflect.Method.invoke(Method.java:566) ~[?:?]
at org.apache.cxf.service.invoker.AbstractInvoker.performInvocation(AbstractInvoker.java:180) ~[cxf-core-3.1.12.jar:3.1.12]
:
:
:
at java.lang.Thread.run(Thread.java:834) [?:?]
[WARN ][SqlExceptionHelper,qtp88259764-236] - SQL Error: 0, SQLState: S1093
[ERROR][SqlExceptionHelper,qtp88259764-236] - The index 3 is out of range.
[DEBUG][HibernateTransactionManager,qtp88259764-236] - Participating transaction failed - marking existing transaction as rollback-only
2. Get any of the InStreamVideoTag subclass entities using Criteria.list() throwing the following error:
org.hibernate.InstantiationException: Cannot instantiate abstract class or interface: : com.domain.businessobject.publisher.InStreamVideoTag
at org.hibernate.tuple.PojoInstantiator.instantiate (PojoInstantiator.java:79)
at org.hibernate.tuple.PojoInstantiator.instantiate (PojoInstantiator.java:105)
at org.hibernate.tuple.entity.AbstractEntityTuplizer.instantiate (AbstractEntityTuplizer.java:705)
at org.hibernate.persister.entity.AbstractEntityPersister.instantiate (AbstractEntityPersister.java:5204)
at org.hibernate.internal.SessionImpl.instantiate (SessionImpl.java:1598)
at org.hibernate.internal.SessionImpl.instantiate (SessionImpl.java:1582)
at org.hibernate.loader.Loader.instanceNotYetLoaded (Loader.java:1755)
at org.hibernate.loader.Loader.getRow (Loader.java:1616)
at org.hibernate.loader.Loader.getRowFromResultSet (Loader.java:740)
at org.hibernate.loader.Loader.getRowsFromResultSet (Loader.java:1039)
at org.hibernate.loader.Loader.processResultSet (Loader.java:990)
at org.hibernate.loader.Loader.doQuery (Loader.java:959)
at org.hibernate.loader.Loader.doQueryAndInitializeNonLazyCollections (Loader.java:349)
at org.hibernate.loader.Loader.doList (Loader.java:2843)
at org.hibernate.loader.Loader.doList (Loader.java:2825)
at org.hibernate.loader.Loader.listIgnoreQueryCache (Loader.java:2657)
at org.hibernate.loader.Loader.list (Loader.java:2652)
at org.hibernate.loader.criteria.CriteriaLoader.list (CriteriaLoader.java:109)
at org.hibernate.internal.SessionImpl.list (SessionImpl.java:1877)
at org.hibernate.internal.CriteriaImpl.list (CriteriaImpl.java:370)
at com.domain.api.commons.dao.impl.AdTagDAOImpl.getVideoTagsByAdTagGrp (AdTagDAOImpl.java:1002)
at com.domain.api.commons.processor.publisher.impl.AdTagProcessorImpl.getVideoTagsByAdTagGrp (AdTagProcessorImpl.java:2423)
at com.domain.publisher.endpoint.AdTagServiceEndpointImpl.getAdTagGroup (AdTagServiceEndpointImpl.java:72)
at com.domain.publisher.endpoint.AdTagServiceEndpointImpl.searchAdTags (AdTagServiceEndpointImpl.java:1341)
at com.domain.publisher.endpoint.AdTagServiceEndpointImpl$$FastClassBySpringCGLIB$$9fdcaf7e.invoke (<generated>)
Note: Tried changing the abstract InStreamVideoTag
into a concrete class. It removed the error but it's not actually loading the RegularInStreamVideoTag
type objects from DB, it's loading InStreamVideoTag
objects only.
Thank you for reading!
Solution 1:[1]
Finally, it's resolved after removing all the @DiscriminatorColumn
& @DiscriminatorValue
annotations on all the classes. Looks like hibernate 5 is strict with the annotations. Now, the generated joined query for retrieving records is similar to Hibernate 4. It uses a special column named clazz
using case
statement to determine the inheritance type. This column will be used by hibernate internally.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | Diablo |