Cannot use identity column key generation with <union-subclass> ( TABLE_PER_CLASS )

55,908

Solution 1

The problem here is that you mix "table-per-class" inheritance and GenerationType.Auto. Consider an identity column in MsSQL. It is column based. In a "table-per-class" strategy you use one table per class and each one has an ID.

Try:

@GeneratedValue(strategy = GenerationType.TABLE)

Solution 2

I wonder if this is a database dialect specific problem, since watching a youtube tutorial with PostgreSQL as the underlying database I saw that the creator of the video run succefully an app with the default @GeneratedValue. In my case (the underlying database is MySQL) I had to modify the @GeneratedValue strategy to GenerationType.TABLE exactly as zoidbeck proposes.

Here is the video : https://www.youtube.com/watch?v=qIdM4KQOtH8

Solution 3

Agree with zoidbeck's answer. You need to change strategy to:

@GeneratedValue(strategy = GenerationType.TABLE)

But that's not all, you need to create a new table, what will hold your abstract's table primary key sequence. Modify your mapping to

@Id
@GeneratedValue(strategy = GenerationType.TABLE, generator = "ConfirmationCodeGenerator")
@TableGenerator(table = "SEQUENCES", name = "ConfirmationCodeGenerator")
public long getConfirmationCode() {
   return confirmationCode;
}

And a new table in database should look like following: enter image description here

When you ran your application, Hibernate will insert a row where sequence_name will be the entity name (SuperClass in this example) and sequence_next_hi_value value will be automatically incremented and used for new records of all implementing subclasses's tables.

Solution 4

In our case, we use a PostreSQL database for dev and production and an in-memory hsqldb database for tests. We are using a sequence in both cases to generate an id. Apparently GenerationType.AUTO defaults to SEQUENCE for postgres, but failed in our local tests (must default to something else for hsqldb).

So the solution that worked for us, explicitly use GenerationType.SEQUENCE.

Solution 5

you can use @MappedSuperclass for inheritance

Share:
55,908

Related videos on Youtube

Admin
Author by

Admin

Updated on October 21, 2020

Comments

  • Admin
    Admin over 3 years

    com.something.SuperClass:

    @Entity
    @Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)
    public abstract class SuperClass implements Serializable {
        private static final long serialVersionUID = -695503064509648117L;
    
        long confirmationCode;
    
        @Id
        @GeneratedValue(strategy = GenerationType.AUTO) // Causes exception!!!
        public long getConfirmationCode() {
            return confirmationCode;
        }
    
        public void setConfirmationCode(long confirmationCode) {
            this.confirmationCode = confirmationCode;
        }
    }
    

    com.something.SubClass:

    @Entity
    public abstract class Subclass extends SuperClass {
        private static final long serialVersionUID = 8623159397061057722L;
    
        String name;
    
        @Column(nullable = false)
        public String getName() {
            return name;
        }
    
        public void setName(String name) {
            this.name = name;
        }
    }
    

    Gives me this exception:

    Caused by: org.hibernate.MappingException: Cannot use identity column key
    generation with <union-subclass> mapping for: com.something.SuperClass
    

    What's the best and most convenient way for me to generate the ID's? I do not want to change my inheritance strategy.

  • Spring Monkey
    Spring Monkey almost 15 years
    Perfect Solution. Even Hibernate forums didnot seem to have this solution, and they were going around the topic forum.hibernate.org/…
  • zoidbeck
    zoidbeck over 11 years
    Postgres is able to do inheritance so you might be right that this is database specific: postgresql.org/docs/8.1/static/ddl-inherit.html The video does not explain (or i missed it) how the schema is generated. So maybe the NHibernate postgres dialect is able to do it by its own or instead you have to add the 'INHERITS' manually. Actually i can not tell.
  • Prashant
    Prashant over 10 years
    Is this issue is with MySql only or its regular as I watch one of a video for Table per class approach and it was working fine in that postgres was used
  • Henning
    Henning about 10 years
    On PostgreSQL, Hibernate defaults to use GenerationType.SEQUENCE. That's why it works automatically there. It has absolutely nothing to do with PostgreSQLs INHERITS.
  • sfitts
    sfitts about 10 years
    I ran into this recently when testing a Dropwizard application. In my case I addressed it by making sure to use the same configuration options used by DW to create the session factory. I'm pretty sure setting the property "hibernate.id.new_generator_mappings" to true is what fixed it. This is DW 0.7.0, Hibernate 4.3.1, DB was H2.
  • Deen John
    Deen John almost 8 years
    i have been using the same tutorial & using @Generated was causing issue as i am using MySql.Spent a lot of time debugging until i saw this post
  • Ram
    Ram almost 6 years
    It works perfectly. However, It is highly recommended not to prefer using 'TABLE' id generation strategy as it triggers lots of queries (select, insert, and update) and maintains locks to generate unique values for primary key. So what would be an alternate solution to this If we have a kinda big Inheritance scenario? It will certainly impact the performance at great extent.