How to Map a Composite Key with JPA and Hibernate

Composite Key with JPA and Hibernate

If you use DB SEQUENCE as the auto generation type only then composite key can work. Otherwise you have to write custom key generator and assign values to both the fields of your composite key before inserting.

@EqualsAndHashCode.Include
@Id
@GeneratedValue(strategy = GenerationType.SEQUENCE)
@Column(name = "id_projeto")
private Long idProjeto;

@EqualsAndHashCode.Include
@Id
@GeneratedValue(strategy = GenerationType.SEQUENCE)
@Column(name = "ra")
private Long ra;

How do I map a One To Many Relationship with Composite Primary Key in JPA (Hibernate)?

These relationships should be mapped a bit differently:

@Entity
@Table("SCHOOL")
public School {
@Column(name = "SCHOOL_ID")
private String schoolId;

@OneToMany(mappedBy="school")
private List<Student> students;
}

@Entity
@Table("STUDENT")
public Student {
@EmbeddedId
private StudentPK studentPK;

@ManyToOne
@MapsId("schoolId")
private School school;
}

@Embeddable
public StudentPK implements Serializable {
@Column(name = "SCHOOL_ID")
private String schoolId;

@Column(name = "STUDENT_ID"
private String studentId;
}

Note the @OneToMany.mappedBy attribute on School.students and @MapsId annotation on Student.school.

Derived identities are discussed (with examples) in the JPA 2.2 spec in section 2.4.1.

Composite primary key of two foreign keys

If you have multiple ids in a entity , you should use EmbeddedId. Here both of your Ids are foreign key constraints , so you need to use @JoinColumn to join them. Sample code for classificacao class and classificacaoId class.

Classificacao.java

@Entity
public class Classificacao implements Serializable {

@Id
ClassificacaoId id;

String name;
// getter and setter

}

ClassificacaoId.java

@Embeddable
public class ClassificacaoId implements Serializable {

@OneToOne
@JoinColumn(name = "userId", referencedColumnName = "userId")
private Usuario usuarioIo;

@ManyToOne
@JoinColumn(name = "tempId", referencedColumnName = "id")
private Temporada temporada;

// getter and setter

}

Generated SQL in h2 db

create table classificacao (
name varchar(255),
user_id varchar(255) not null,
temp_id bigint not null,
primary key (temp_id, user_id)
);
create table temporada (
id bigint not null,
name varchar(255),
primary key (id)
);
create table usuario (
user_id varchar(255) not null,
name varchar(255),
primary key (user_id)
);
alter table classificacao add constraint FK1najxwr5x189iul4rguqc4wyx
foreign key (user_id) references usuario;
alter table classificacao add constraint FKlvk517howhduqt5ghb4mgx0ko
foreign key (temp_id) references temporada;

Map primary key to composite key in JPA

Remove the mappedBy attribute. This attribute is used when you have bidirectional relationship to indicate which side of the relationship is the owner.

But you will need to set the Foreign Key aka JoinColumn

@JoinColumn("user_id")
@OneToMany(fetch = FetchType.LAZY)
private UserSession userSession;

How to define composite foreign key mapping in hibernate?

We need to put both key in @Embeddable to detach compound key thenafter, put it in User Entity using @EmbeddedId and map both primary key using Hibernate Relational Mapping...

There are two option to Composite Primary Key:

  1. Using @EmbeddedId
  2. Using @IdClass()

Here down is example:

----------------------------------- Using EmbeddedId -----------------------------------

Compound primary key:

@Embeddable
public class UserIdName implements Serializable {
int id;
String name;

// getter and setter
}

User:

@Entity
@Table(name = "users")
public class USER{
@EmbeddedId
private UserIdName id;

String department;

@OneToMany(cascade = CascadeType.ALL, mappedBy = "user")
private Set<Userdetail> userdetail;

// getter and setter
}

UserDetails:

@Entity
@Table(name = "Userdetail")
public class Userdetail {

@Id
private int detail_id;

@ManyToOne
@JoinColumns({ @JoinColumn(name = "id", referencedColumnName = "id"),
@JoinColumn(name = "name", referencedColumnName = "name") })
private USER user;

String address;

String otherFields;

// getter setter
}

----------------------------------- Using IdClass -----------------------------------

Compound primary key:

public class UserIdName implements Serializable {
int id;
String name;

// getter and setter
}

User:

@Entity
@Table(name = "users")
@IdClass(UserIdName.class)
public class USER{
@Id
int id;

@Id
String name;

String department;

@OneToMany(cascade = CascadeType.ALL, mappedBy = "user")
private Set<Userdetail> userdetail;

// getter and setter
}

UserDetails:

@Entity
@Table(name = "Userdetail")
public class Userdetail {

@Id
private int detail_id;

@ManyToOne
@JoinColumns({ @JoinColumn(name = "id", referencedColumnName = "id"),
@JoinColumn(name = "name", referencedColumnName = "name") })
private USER user;

String address;

String otherFields;

// getter setter
}

-> If you wanna insert both foreign key manually try below code

Put this code in UserDetails

@ManyToOne
@JoinColumn(name = "id", referencedColumnName = "id", insertable = false, updatable = false)
@JoinColumn(name = "name", referencedColumnName = "name", insertable = false, updatable = false)
private USER user;

@Column(name="id")
private int id;

@Column(name="name")
private String name

// don't forget to put getter setter

User Table:

Sample Image

User Detail Table:

Sample Image

How to delete/search existence by Composite Primary Key in Spring data JPA?

@Embeddable and @EmbeddedId annotations can serve the purpose here.

First, you can annotate your TokenId class with @Embeddable class level annotation as follows:

@Embeddable
public class TokenId {

@Column(name="field1")
private String field1;

@Column(name="field2")
private String field2;
}

Then use the above Embeddable class as embeddedId in parent class as follows:

@Entity
@NoArgsConstructor
@AllArgsConstructor
public class Token {

@EmbeddedId
private TokenId id;

@NotNull
private long expiration;

private boolean active;

private boolean setActive;
}


Related Topics



Leave a reply



Submit