why same Id on @MappedSuperclass when @Inheritance(strategy=InheritanceType.TABLE_PER_CLASS)

2.5k views Asked by At

I try to have 2 tables, as follows:

MISExercise (table)


ID NAME ...

2 a


MISInteractiveExercise(table)


ID NAME ...

1 b


They must have no same id. And they are inherited from the same base. My code is :

@MappedSuperclass  
@Inheritance(strategy=InheritanceType.TABLE_PER_CLASS)
public abstract class MISExerciseBase {
    @Id
    @GeneratedValue(strategy = GenerationType.TABLE)
    private Integer id; 

    ...
}

@Entity
public class MISExercise extends MISExerciseBase{
   ...
}

@Entity
public class MISInteractiveExercise extends MISExerciseBase{
   ...
}

Unfortunately, I find that the table of MISExercise and the table of MISInteractiveExercise can have the same id. When I google it I find http://openjpa.208410.n2.nabble.com/same-Id-on-mapped-superclass-td2435374.html. @Kaayan seems has the same problem. But I can't get help from that page.

And it seems if I use @Entity not @MappedSuperclass, it will be fine. But why, and what's the good way?

2

There are 2 answers

5
SpartanElite On

As both your classes MISExercise and MISInteractiveExersice both inherit from MISExerciseBase, and you have set your Generation Strategy as @GeneratedValue(strategy = GenerationType.TABLE), your id's are not going to be unique across all your tables, but only unique per table.

If you would like to have unique id across multiple tables, ie in your case MISExercise and MISInteractiveExerice, you need to change your generation Strategy to Auto.

So to fix your problem change your abstract class MISExerciseBase to this...

@MappedSuperclass  
@Inheritance(strategy=InheritanceType.TABLE_PER_CLASS)
public abstract class MISExerciseBase {
    @Id
    @GeneratedValue(strategy=GenerationType.AUTO) //NOTE This Change to AUTO
    private Integer id; 

    ...
}
0
Forrest On

I ran into a similar issue. This fixed it for me by adding this as a class level annotation:

@SequenceGenerator(initialValue = 1, name = "idgen", sequenceName = "parentseq", allocationSize = 1)

You don't need to specify ALL that stuff, but the important part is the sequenceName and making sure that the child classes are using the same one as the parent class.