Uploaded image for project: 'Hibernate ORM'
  1. HHH-9302

SQLGrammarException with @DiscriminatorColumn in an inheritance hierarchy

    Details

    • Type: Bug
    • Status: Closed
    • Priority: Major
    • Resolution: Fixed
    • Affects Version/s: 4.3.1, 4.3.2, 4.3.3, 4.3.4, 4.3.5, 4.3.6, 5.0.0.Final, 5.0.1, 5.0.2, 5.0.3
    • Fix Version/s: 5.0.5
    • Component/s: hibernate-core
    • Environment:
      Hibernate Core/EntityManager 4.3.6.Final
      Java 1.7
    • Bug Testcase Reminder (view):

      Bug reports should generally be accompanied by a test case!

    • Last commented by a user?:
      true
    • Sprint:

      Description

      I recently stumbled upon a possible bug with the discriminator column in an inheritance hierarchy.

      You can find the appropiate test case here: https://github.com/shiruba/hibernate-discriminatorvalue-test

      Suppose I got the following inheritance hierarchy:

      @Entity
      @Inheritance(strategy = InheritanceType.JOINED)
      @DiscriminatorColumn
      public class Parent {}
      
      @Entity
      public class SpecialParent extends Parent {}
      
      @Entity
      public class VerySpecialParent extends SpecialParent {}
      

      If I try to persist an instance of SpecialParent, I get the following stacktrace:

      INFO: HHH000327: Error performing load command : org.hibernate.exception.SQLGrammarException: could not extract ResultSet

      javax.persistence.PersistenceException: org.hibernate.exception.SQLGrammarException: could not extract ResultSet
      	at org.hibernate.jpa.spi.AbstractEntityManagerImpl.convert(AbstractEntityManagerImpl.java:1763)
      	at org.hibernate.jpa.spi.AbstractEntityManagerImpl.convert(AbstractEntityManagerImpl.java:1677)
      	at org.hibernate.jpa.spi.AbstractEntityManagerImpl.convert(AbstractEntityManagerImpl.java:1683)
      	at org.hibernate.jpa.spi.AbstractEntityManagerImpl.merge(AbstractEntityManagerImpl.java:1206)
      	at de.codecentric.hibernate.DiscriminatorColumnTest.testDiscriminatorValueInInheritanceWithConcreteType(DiscriminatorColumnTest.java:22)
      	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
      	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
      	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
      	at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:47)
      	at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
      	at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:44)
      	at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
      	at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:271)
      	at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:70)
      	at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:50)
      	at org.junit.runners.ParentRunner$3.run(ParentRunner.java:238)
      	at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:63)
      	at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:236)
      	at org.junit.runners.ParentRunner.access$000(ParentRunner.java:53)
      	at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:229)
      	at org.junit.runners.ParentRunner.run(ParentRunner.java:309)
      	at org.junit.runner.JUnitCore.run(JUnitCore.java:160)
      	at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:74)
      	at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:211)
      	at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:67)
      	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
      	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
      	at com.intellij.rt.execution.application.AppMain.main(AppMain.java:134)
      Caused by: org.hibernate.exception.SQLGrammarException: could not extract ResultSet
      	at org.hibernate.exception.internal.SQLExceptionTypeDelegate.convert(SQLExceptionTypeDelegate.java:80)
      	at org.hibernate.exception.internal.StandardSQLExceptionConverter.convert(StandardSQLExceptionConverter.java:49)
      	at org.hibernate.engine.jdbc.spi.SqlExceptionHelper.convert(SqlExceptionHelper.java:126)
      	at org.hibernate.engine.jdbc.spi.SqlExceptionHelper.convert(SqlExceptionHelper.java:112)
      	at org.hibernate.engine.jdbc.internal.ResultSetReturnImpl.extract(ResultSetReturnImpl.java:91)
      	at org.hibernate.loader.Loader.getResultSet(Loader.java:2065)
      	at org.hibernate.loader.Loader.executeQueryStatement(Loader.java:1862)
      	at org.hibernate.loader.Loader.executeQueryStatement(Loader.java:1838)
      	at org.hibernate.loader.Loader.doQuery(Loader.java:909)
      	at org.hibernate.loader.Loader.doQueryAndInitializeNonLazyCollections(Loader.java:354)
      	at org.hibernate.loader.Loader.doQueryAndInitializeNonLazyCollections(Loader.java:324)
      	at org.hibernate.loader.Loader.loadEntity(Loader.java:2148)
      	at org.hibernate.loader.entity.AbstractEntityLoader.load(AbstractEntityLoader.java:78)
      	at org.hibernate.loader.entity.AbstractEntityLoader.load(AbstractEntityLoader.java:68)
      	at org.hibernate.persister.entity.AbstractEntityPersister.load(AbstractEntityPersister.java:4126)
      	at org.hibernate.event.internal.DefaultLoadEventListener.loadFromDatasource(DefaultLoadEventListener.java:503)
      	at org.hibernate.event.internal.DefaultLoadEventListener.doLoad(DefaultLoadEventListener.java:468)
      	at org.hibernate.event.internal.DefaultLoadEventListener.load(DefaultLoadEventListener.java:213)
      	at org.hibernate.event.internal.DefaultLoadEventListener.proxyOrLoad(DefaultLoadEventListener.java:275)
      	at org.hibernate.event.internal.DefaultLoadEventListener.onLoad(DefaultLoadEventListener.java:151)
      	at org.hibernate.internal.SessionImpl.fireLoad(SessionImpl.java:1070)
      	at org.hibernate.internal.SessionImpl.access$2000(SessionImpl.java:176)
      	at org.hibernate.internal.SessionImpl$IdentifierLoadAccessImpl.load(SessionImpl.java:2551)
      	at org.hibernate.internal.SessionImpl.get(SessionImpl.java:960)
      	at org.hibernate.event.internal.DefaultMergeEventListener.entityIsDetached(DefaultMergeEventListener.java:306)
      	at org.hibernate.event.internal.DefaultMergeEventListener.onMerge(DefaultMergeEventListener.java:186)
      	at org.hibernate.event.internal.DefaultMergeEventListener.onMerge(DefaultMergeEventListener.java:85)
      	at org.hibernate.internal.SessionImpl.fireMerge(SessionImpl.java:876)
      	at org.hibernate.internal.SessionImpl.merge(SessionImpl.java:858)
      	at org.hibernate.internal.SessionImpl.merge(SessionImpl.java:863)
      	at org.hibernate.jpa.spi.AbstractEntityManagerImpl.merge(AbstractEntityManagerImpl.java:1196)
      	... 27 more
      Caused by: com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException: Unknown column 'specialpar0_.DTYPE' in 'field list'
      	at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
      	at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
      	at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
      	at java.lang.reflect.Constructor.newInstance(Constructor.java:408)
      	at com.mysql.jdbc.Util.handleNewInstance(Util.java:408)
      	at com.mysql.jdbc.Util.getInstance(Util.java:383)
      	at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:1062)
      	at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:4226)
      	at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:4158)
      	at com.mysql.jdbc.MysqlIO.sendCommand(MysqlIO.java:2615)
      	at com.mysql.jdbc.MysqlIO.sqlQueryDirect(MysqlIO.java:2776)
      	at com.mysql.jdbc.ConnectionImpl.execSQL(ConnectionImpl.java:2840)
      	at com.mysql.jdbc.PreparedStatement.executeInternal(PreparedStatement.java:2082)
      	at com.mysql.jdbc.PreparedStatement.executeQuery(PreparedStatement.java:2212)
      	at org.hibernate.engine.jdbc.internal.ResultSetReturnImpl.extract(ResultSetReturnImpl.java:82)
      	... 53 more
      

      If I remove the @DiscriminatorColumn annotation at Parent, everything works fine. This led me to reading the spec and paragraph 11.1.12, which I understand as follows:

      • The @DiscriminatorColumn annotation is optional for the SINGLE_TABLE and JOINED inheritance strategies.
      • In case no @DiscriminatorColumn is specified, the discriminator column name defaults to DTYPE and the type to STRING.
      • A @DiscriminatorColumn has to be specified at the root of the inheritance hierarchy.
      • A @DiscriminatorColumn can be used in a subhierarchy in which a different inheritance strategy shall be applied.
      • A @DiscriminatorValue will be generated, if none was provided.

      Obviously, Hibernate expects the discriminator column to be somewhere else, but not on the direct super class.

      This leads to my question: Is this a bug OR is this a configuration issue (in which case Hibernate should not generate invalid SQL but throw an exception of some kind)?

        Attachments

          Issue links

            Activity

              People

              • Votes:
                5 Vote for this issue
                Watchers:
                8 Start watching this issue

                Dates

                • Created:
                  Updated:
                  Resolved: