title: Hibernate 5 migration Issue with Multilevel Joined table Inheritance with Hibernate 5.4 DiscriminatorColumn
body: <p>I am working on migrating a legacy <code>Hibernate</code> project from version <code>4.1</code> to <code>5.4</code>. The code has <em>Multilevel Joined table inheritance</em> using a dedicated <code>DiscriminatorColumn</code>. The code was working fine in Hibernate 4 but throwing errors in Hibernate 5.</p>
  <p><em>In-Short <strong>class hierarchy</strong> is like:</em></p>
  <p><a href="https://i.stack.imgur.com/fySeO.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/fySeO.png" alt="enter image description here" /></a></p>
  <p>And, the <strong>code</strong> looks like:</p>
  <h2>First level Super class</h2>
  <pre><code>@Entity
  @Table(name=&quot;VideoTag&quot;)
  @Inheritance(strategy = InheritanceType.JOINED)
  @DiscriminatorColumn(name = &quot;VideoTagType&quot;, discriminatorType = DiscriminatorType.INTEGER)
  @DiscriminatorOptions(force=true)
  public abstract class VideoTag implements Cloneable {
      
      @Id
      @Column(name = &quot;AdTagId&quot;)
      private Long adTagId;
  
      @Column(name = &quot;VideoTagType&quot;)
      @Type(type = &quot;enum_pub_video_tag_type&quot;)
      private VideoTagType videoTagType;
      
      //Non-important columns
  
      //Accessors 
  }
  </code></pre>
  <h2>Second level classes</h2>
  <h5>Simple sub-class:</h5>
  <pre><code>@Entity
  @DiscriminatorValue(value = &quot;2&quot;)
  @Table(name = &quot;OutstreamVideoTag&quot;)
  public class OutStreamVideoTag extends VideoTag implements Cloneable {
          
      //Non-important columns
  
      //Accessors 
  }
  </code></pre>
  <hr />
  <h5>Complex sub-class/Second level super class</h5>
  <pre><code>@Entity
  @DiscriminatorValue(value = &quot;1&quot;)
  @Table(name = &quot;InStreamVideoTag&quot;)
  @Inheritance(strategy = InheritanceType.JOINED)
  @DiscriminatorColumn(name = &quot;InstreamVideoTagType&quot;, discriminatorType = DiscriminatorType.INTEGER)
  public abstract class InStreamVideoTag extends VideoTag implements Cloneable {
  
      @Column(name = &quot;InstreamVideoTagType&quot;)
      @Type(type = &quot;enum_pub_instream_video_tag_type&quot;)
      private InstreamVideoTagType instreamVideoTagType;
      
      //Non-important columns
  
      //Accessors 
      
  }
  </code></pre>
  <h2>Last level Sub-classes</h2>
  <pre><code>@Entity
  @DiscriminatorValue(value = &quot;1&quot;)
  @Table(name = &quot;RegularInStreamVideoTag&quot;)
  public class RegularInStreamVideoTag extends InStreamVideoTag implements Cloneable {
      //Non-important columns
  
      //Accessors 
  }
  </code></pre>
  <hr />
  <pre><code>@Entity
  @DiscriminatorValue(value = &quot;2&quot;)
  @Table(name = &quot;InAppInstreamVideoTag&quot;)
  public class InAppInstreamVideoTag extends InStreamVideoTag implements Cloneable {
          
      //Non-important columns
  
      //Accessors 
  }
  </code></pre>
  <hr />
  <h2>Errors</h2>
  <p><strong>1. Save of RegularInStreamVideoTag entity is throwing the following error:</strong></p>
  <pre><code>[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(&lt;generated&gt;) ~[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(&lt;generated&gt;) ~[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
  </code></pre>
  <p><strong>2. Get any of the InStreamVideoTag subclass entities using Criteria.list() throwing the following error:</strong></p>
  <pre><code>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 (&lt;generated&gt;)
  </code></pre>
  <p><em>Note:</em> Tried changing the abstract <code>InStreamVideoTag</code> into a concrete class. It removed the error but it's not actually loading the <code>RegularInStreamVideoTag</code> type objects from DB, it's loading <code>InStreamVideoTag</code> objects only.</p>
  <p>Thank you for reading!</p>