Single Table Inheritance WITHOUT Discriminator column

Viewed 19894

Good Morning, my Dear comrades,

This is starting to be come annoying - a simple thing, but hours of struggle, am I getting old??

I am trying to map two Classes to a single table using JPA by Hibernate. The idea is to have only a small subset of columns in parent Class, and bigger/full set in the child Class. There is NO TABLE inheritance involved, only class inheritance. How can this be accomplished??

Doing this will not work:

@Entity
@Table(name = "the_table")
class Parent implements Serializable {
}

@Entity
@Table(name = "the_table")
class Child extends Parent implements Serializable {
}

Hibernate assumes default inheritance strategy InheritanceType.SINGLE_TABLE, and is looking for discriminator column - DTYPE by default. But wait - there is no table inheritance, having the discriminator column does not make sence.

I have also taken a look at PolymorphismType.EXPLICIT which did not make any difference. The stack trace is:

Caused by: com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException: Unknown column 'apprentice0_.DTYPE' in 'where clause'
   at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
   at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:39)
   at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:27)
   at java.lang.reflect.Constructor.newInstance(Constructor.java:513)
   at com.mysql.jdbc.Util.handleNewInstance(Util.java:411)
   at com.mysql.jdbc.Util.getInstance(Util.java:386)
   at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:1052)
   at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:3597)
   at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:3529)
   at com.mysql.jdbc.MysqlIO.sendCommand(MysqlIO.java:1990)
   at com.mysql.jdbc.MysqlIO.sqlQueryDirect(MysqlIO.java:2151)
   at com.mysql.jdbc.ConnectionImpl.execSQL(ConnectionImpl.java:2625)
   at com.mysql.jdbc.PreparedStatement.executeInternal(PreparedStatement.java:2119)
   at com.mysql.jdbc.PreparedStatement.executeQuery(PreparedStatement.java:2281)
   at com.mchange.v2.c3p0.impl.NewProxyPreparedStatement.executeQuery(NewProxyPreparedStatement.java:76)
   at org.hibernate.jdbc.AbstractBatcher.getResultSet(AbstractBatcher.java:208)
   at org.hibernate.loader.Loader.getResultSet(Loader.java:1808)
   at org.hibernate.loader.Loader.doQuery(Loader.java:697)
   at org.hibernate.loader.Loader.doQueryAndInitializeNonLazyCollections(Loader.java:259)
   at org.hibernate.loader.Loader.loadEntity(Loader.java:1881)

yeah, one more thing:

The @MappedSuperclass and @Embeddable are of no use as these can not be used in conjunction with @Entity - the parent class has to be an @Entity itself as it is being used for persistence elsewhere.

5 Answers

If you don't want to add auto dtype column, you should define your own Discriminator by @DiscriminatorFormula

@Entity
@Table(name = "CS_CUSTOMER")
@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
@DiscriminatorFormula("case when id < 3 then 'VIP' else 'Customer' end")
public class Customer extends BaseEntity {
...
@Entity
public class VIP extends Customer {
...

The Discriminator name is default to Entity class name, if you want to change it, use

@DiscriminatorValue("VIP")  

Log from hibernate

Hibernate: create sequence hibernate_sequence start with 1 increment by 1
Hibernate: 

    create table cs_customer (
       id bigint not null,
        create_user_id bigint,
        first_name varchar(255),
        last_name varchar(255),
        primary key (id)
    )
Related