6

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.

1
  • Do you still see any issues provided in the answer below? Commented Nov 24, 2017 at 5:59

3 Answers 3

7
+50

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

Sign up to request clarification or add additional context in comments.

6 Comments

if you find the answer helpful kindly share the bounty points. If you need any further clarification pls ask.
Actually it doens't solve my problem because i didn't want to have the "id" column... the perfect primary key is the userId if I put it in the abstract class i've the problem i got, if i take off, and put in each exteded class i get incompabilities
I understand your problem is with PotenicalRegister class where with your implementation id and userId cols become part of primary key as this is inherited from abstract class. With my solution you can have the primary key defined as you want there is no primary key in the abstract class and each implementation of the register class can have its pwn primay key.
Kindly let me know what incompatibilities you get when you add @Id attribute in each extended class so that we can provide you a solution.
I got an exception when removing @Id from the base class. I couldn't figure out what's I'm missing. Can you help? Error creating bean with name 'registerRepository': Invocation of init method failed; nested exception is java.lang.IllegalArgumentException: This class [....Register] does not define an IdClass
|
1

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).

Comments

0

you can't redefine userId as a primary key: https://hibernate.atlassian.net/browse/HHH-11771. So i believe you should consider moving userId from abstract class to implementations with appropriate annotations.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.