title: Does Hibernate have a limit on extending inherited Entity classes?
body: <p>I have a Java application that is deployed using Spring-Boot. The application inherits JPA Entities several layers deep. I had previously used EclipseLink, but I am now converting it to use Hibernate. I am running into a problem that I had not had with EclipseLink.</p>
  
  <p>I have "entity-d" that extends "entity-c" that extends "entity-b" that extends "entity-a". The inheritance goes 4 levels deep, and Hibernate throws an Exception when I start the application. If I remove the last Entity (entity-d) so that it is only 3 levels deep, then the application starts without the Exception.</p>
  
  <p>Here are some sample entities that I put together to demonstrate the problem:</p>
  
  <p>BaseEntity:</p>
  
  <pre><code>package test.entities;
  
  import javax.persistence.Column;
  import javax.persistence.DiscriminatorColumn;
  import javax.persistence.Entity;
  import javax.persistence.Id;
  import javax.persistence.Inheritance;
  import javax.persistence.InheritanceType;
  import javax.persistence.PrimaryKeyJoinColumn;
  import javax.persistence.SecondaryTable;
  import javax.persistence.SecondaryTables;
  import javax.persistence.Table;
  
  import static javax.persistence.DiscriminatorType.INTEGER;
  
  @Entity
  @Table (name = "base")
  @SecondaryTables ({@SecondaryTable (
      name                     = "second",
      pkJoinColumns            = {@PrimaryKeyJoinColumn (
          name                 = "id",
          referencedColumnName = "id"
      ) }
  ) })
  @DiscriminatorColumn (
  name                     = "item_type",
  discriminatorType        = INTEGER
  )
  @Inheritance (strategy = InheritanceType.JOINED)
  public class BaseEntity
  {
      public BaseEntity () {}
  
      @Id
      @Column (
          name     = "id",
          unique   = true,
          nullable = false
      )
      private Integer id;
      @Column (
          name       = "item_type",
          nullable   = false,
          insertable = false,
          updatable  = false
      )
      private Integer itemType;
      @Column (name = "column_a")
      private Integer columnA;
  
      public Integer getId () { return this.id; }
      public void setId (Integer id) { this.id = id; }
  
      public Integer getItemType () { return this.itemType; }
  
      public Integer getColumnA () { return this.columnA; }
      public void setColumnA (Integer columnA) { this.columnA = columnA; }
  }
  </code></pre>
  
  <p>SecondEntity:</p>
  
  <pre><code>package test.entities;
  
  import javax.persistence.Column;
  import javax.persistence.DiscriminatorValue;
  import javax.persistence.Entity;
  import javax.persistence.Inheritance;
  import javax.persistence.InheritanceType;
  import javax.persistence.PrimaryKeyJoinColumn;
  import javax.persistence.SecondaryTable;
  import javax.persistence.SecondaryTables;
  import javax.persistence.Table;
  
  @Entity
  @Table ( name = "second" )
  @SecondaryTables (
      {
          @SecondaryTable (
              name                     = "third",
              pkJoinColumns            =
                      {
                          @PrimaryKeyJoinColumn (
                              name                 = "id",
                              referencedColumnName = "id"
                          )
                      }
          )
      }
  )
  @Inheritance (strategy = InheritanceType.JOINED)
  @DiscriminatorValue("2")
  public class SecondEntity extends BaseEntity
  {
      public SecondEntity() {}
  
      @Column (name = "column_b")
      private Integer columnB;
  
      public Integer getColumnB() { return this.columnB; }
      public void setColumnB(Integer columnB) { this.columnB = columnB; }
  }
  </code></pre>
  
  <p>ThirdEntity:</p>
  
  <pre><code>package test.entities;
  
  import javax.persistence.Column;
  import javax.persistence.DiscriminatorValue;
  import javax.persistence.Entity;
  import javax.persistence.Table;
  
  @Entity
  @Table ( name = "third" )
  @DiscriminatorValue("3")
  public class ThirdEntity extends SecondEntity
  {
      public ThirdEntity() {}
  
      @Column (name = "column_c")
      private Integer columnC;
  
      public Integer getColumnC() { return this.columnC; }
      public void setColumnC(Integer columnC) { this.columnC = columnC; }
  }
  </code></pre>
  
  <p>FourthEntity:</p>
  
  <pre><code>package test.entities;
  
  import javax.persistence.DiscriminatorValue;
  import javax.persistence.Entity;
  
  @Entity
  @DiscriminatorValue("4")
  public class FourthEntity extends ThirdEntity
  {
      public FourthEntity() {}
  }
  </code></pre>
  
  <p>Running the application throws the following exception:</p>
  
  <pre><code>Error starting ApplicationContext. To display the auto-configuration report enabled debug logging (start with --debug)
  
  
  2015-06-24 21:33:05.868 ERROR 3761 --- [           main] o.s.boot.SpringApplication               : Application startup failed
  
  org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'entityManagerFactory' defined in test.Application: Invocation of init method failed; nested exception is java.lang.ArrayIndexOutOfBoundsException: 2
          at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1574)
          at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:539)
          at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:476)
          at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:303)
          at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230)
          at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:299)
          at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:194)
          at org.springframework.context.support.AbstractApplicationContext.getBean(AbstractApplicationContext.java:956)
          at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:747)
          at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:480)
          at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.refresh(EmbeddedWebApplicationContext.java:118)
          at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:686)
          at org.springframework.boot.SpringApplication.run(SpringApplication.java:320)
          at org.springframework.boot.SpringApplication.run(SpringApplication.java:957)
          at org.springframework.boot.SpringApplication.run(SpringApplication.java:946)
          at test.Application.main(Application.java:73)
          at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
          at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
          at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
          at java.lang.reflect.Method.invoke(Method.java:606)
          at org.springframework.boot.loader.MainMethodRunner.run(MainMethodRunner.java:53)
          at java.lang.Thread.run(Thread.java:745)
  Caused by: java.lang.ArrayIndexOutOfBoundsException: 2
          at org.hibernate.persister.entity.JoinedSubclassEntityPersister.isNullableTable(JoinedSubclassEntityPersister.java:800)
          at org.hibernate.persister.entity.AbstractEntityPersister.determineSubclassTableJoinType(AbstractEntityPersister.java:3814)
          at org.hibernate.persister.entity.AbstractEntityPersister.createJoin(AbstractEntityPersister.java:3787)
          at org.hibernate.persister.entity.AbstractEntityPersister.fromJoinFragment(AbstractEntityPersister.java:3739)
          at org.hibernate.persister.entity.AbstractEntityPersister.generateSnapshotSelectString(AbstractEntityPersister.java:1791)
          at org.hibernate.persister.entity.AbstractEntityPersister.doLateInit(AbstractEntityPersister.java:3991)
          at org.hibernate.persister.entity.AbstractEntityPersister.postInstantiate(AbstractEntityPersister.java:4015)
          at org.hibernate.internal.SessionFactoryImpl.&lt;init&gt;(SessionFactoryImpl.java:481)
          at org.hibernate.cfg.Configuration.buildSessionFactory(Configuration.java:1859)
          at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl$4.perform(EntityManagerFactoryBuilderImpl.java:852)
          at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl$4.perform(EntityManagerFactoryBuilderImpl.java:845)
          at org.hibernate.boot.registry.classloading.internal.ClassLoaderServiceImpl.withTccl(ClassLoaderServiceImpl.java:398)
          at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.build(EntityManagerFactoryBuilderImpl.java:844)
          at org.springframework.orm.jpa.vendor.SpringHibernateJpaPersistenceProvider.createContainerEntityManagerFactory(SpringHibernateJpaPersistenceProvider.java:60)
          at org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean.createNativeEntityManagerFactory(LocalContainerEntityManagerFactoryBean.java:343)
          at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.afterPropertiesSet(AbstractEntityManagerFactoryBean.java:318)
          at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1633)
          at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1570)
          ... 21 common frames omitted
  
  java.lang.reflect.InvocationTargetException
          at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
          at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
          at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
          at java.lang.reflect.Method.invoke(Method.java:606)
          at org.springframework.boot.loader.MainMethodRunner.run(MainMethodRunner.java:53)
          at java.lang.Thread.run(Thread.java:745)
  Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'entityManagerFactory' defined in test.Application: Invocation of init method failed; nested exception is java.lang.ArrayIndexOutOfBoundsException: 2
          at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1574)
          at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:539)
          at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:476)
          at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:303)
          at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230)
          at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:299)
          at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:194)
          at org.springframework.context.support.AbstractApplicationContext.getBean(AbstractApplicationContext.java:956)
          at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:747)
          at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:480)
          at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.refresh(EmbeddedWebApplicationContext.java:118)
          at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:686)
          at org.springframework.boot.SpringApplication.run(SpringApplication.java:320)
          at org.springframework.boot.SpringApplication.run(SpringApplication.java:957)
          at org.springframework.boot.SpringApplication.run(SpringApplication.java:946)
          at test.Application.main(Application.java:73)
          ... 6 more
  Caused by: java.lang.ArrayIndexOutOfBoundsException: 2
          at org.hibernate.persister.entity.JoinedSubclassEntityPersister.isNullableTable(JoinedSubclassEntityPersister.java:800)
          at org.hibernate.persister.entity.AbstractEntityPersister.determineSubclassTableJoinType(AbstractEntityPersister.java:3814)
          at org.hibernate.persister.entity.AbstractEntityPersister.createJoin(AbstractEntityPersister.java:3787)
          at org.hibernate.persister.entity.AbstractEntityPersister.fromJoinFragment(AbstractEntityPersister.java:3739)
          at org.hibernate.persister.entity.AbstractEntityPersister.generateSnapshotSelectString(AbstractEntityPersister.java:1791)
          at org.hibernate.persister.entity.AbstractEntityPersister.doLateInit(AbstractEntityPersister.java:3991)
          at org.hibernate.persister.entity.AbstractEntityPersister.postInstantiate(AbstractEntityPersister.java:4015)
          at org.hibernate.internal.SessionFactoryImpl.&lt;init&gt;(SessionFactoryImpl.java:481)
          at org.hibernate.cfg.Configuration.buildSessionFactory(Configuration.java:1859)
          at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl$4.perform(EntityManagerFactoryBuilderImpl.java:852)
          at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl$4.perform(EntityManagerFactoryBuilderImpl.java:845)
          at org.hibernate.boot.registry.classloading.internal.ClassLoaderServiceImpl.withTccl(ClassLoaderServiceImpl.java:398)
          at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.build(EntityManagerFactoryBuilderImpl.java:844)
          at org.springframework.orm.jpa.vendor.SpringHibernateJpaPersistenceProvider.createContainerEntityManagerFactory(SpringHibernateJpaPersistenceProvider.java:60)
          at org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean.createNativeEntityManagerFactory(LocalContainerEntityManagerFactoryBean.java:343)
          at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.afterPropertiesSet(AbstractEntityManagerFactoryBean.java:318)
          at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1633)
          at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1570)
          ... 21 more
  </code></pre>
  
  <p>If I remove the FourthEntity class (or just remove the @Entity annotation from the file) then I can run the application without Hibernate throwing an exception.</p>