Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Hibernate inheritance with different primary key

I'm trying to create a inheritance with TABLE_PER_CLASS strategy, but i want to have different primary key for each table is it possible?

I've one class Register which has millions of instances, some of these instances are "special" and have different rules for theirs columns and extra columns.

@MappedSuperclass

public abstract class Register {


    @Id
    @Column(nullable = false, unique = true, updatable = false)
    private Long userId;


    private Date checked;

    @Column(nullable = false)
    private RegisterState tipo;
}


@Entity
@AttributeOverrides({ @AttributeOverride(name = "userId", column = @Column(nullable = false, unique = false, updatable = false)) })
public class PotencialRegister extends Register implements Serializable {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Integer id;


    @Column(length = 64, nullable = false, unique = false)
    private String referer;
}

For the basic register I dont need an Id attribute because I've one unique column, but for the specialized entity that column is not unique so I added an extra attribute.

the problem is that hibernate is using the parent id to created a composite primary key (the generated schema is):

create table PotencialRegister (
        id integer not null,
        userId bigint not null,
        checked datetime(6),
        tipo integer not null,
        referer varchar(64) not null,
        primary key (id, userId)
    )  

    create table Register (
        userId bigint not null,
        checked datetime(6),
        tipo integer not null,
        primary key (userId)
    )  

The columns are right and the schama is what i want, but I would like to remove the "id" member from PotencialRegister primary key.

like image 201
Rafael Lima Avatar asked Jan 30 '23 06:01

Rafael Lima


2 Answers

You can create another class that do not have @Id column in it and use this class as base class for each type of Register.

so your Register class would look like:

@MappedSuperclass

public abstract class Register {

    @Column(nullable = false, unique = true, updatable = false)
    private Long userId;

    private Date checked;

   @Column(nullable = false)
    private RegisterState tipo;
}

Now for your Normal Register you can do following:

 @Entity   
 public class NormalRegister extends Register implements Serializable{

    @Id
    public Long getUserId(){
      return super.userId;
    }

     public void setUserId(Long uId){
        super.userId=uId;
      }

   }

next you define your PotencialRegister class as:

@Entity
@AttributeOverrides({ @AttributeOverride(name = "userId", column = @Column(nullable = false, unique = false, updatable = false)) })
public class PotencialRegister extends Register implements Serializable {

    private Integer id;


    @Column(length = 64, nullable = false, unique = false)
    private String referer;

    @Id
    public Long getUserId(){
      return super.userId;
    }

     public void setUserId(Long uId){
        super.userId=uId;
      }

}

With this you do not have Id in base class and all the sub classes can define their own Id attribute

like image 169
Ravik Avatar answered Feb 02 '23 10:02

Ravik


In table per class hierarchy both Version and Id properties are assumed to be inherited from the root class. If I am not wrong then you cannot use multiple Id attributes in single class/class hierarchy. In your case in the base class you can put the properties which are common across tables and use Id attribute only in the specific classes (representing the individual tables).

like image 45
Har Krishan Avatar answered Feb 02 '23 10:02

Har Krishan