A composite key means the primary key of a table is made up of two or more columns, and you need to map this combined key in your entity.
In Hibernate (and JPA), you implement composite keys using either:
@Embeddable
+@EmbeddedId
→ recommended, modern, type-safe approach.@IdClass
→ older, more verbose alternative.
🔹 Approach 1: @Embeddable
+ @EmbeddedId
(recommended)
✅ Step 1: Create a key class annotated with @Embeddable
@Embeddable
public class EnrollmentId implements Serializable {
private Long studentId;
private Long courseId;
// Must have default constructor, getters/setters, equals, and hashCode!
public EnrollmentId() {}
// getters, setters, equals, hashCode...
}
✅ Step 2: Use @EmbeddedId
in your entity
@Entity
public class Enrollment {
@EmbeddedId
private EnrollmentId id;
@ManyToOne
@MapsId("studentId") // maps studentId in EnrollmentId
@JoinColumn(name = "student_id")
private Student student;
@ManyToOne
@MapsId("courseId") // maps courseId in EnrollmentId
@JoinColumn(name = "course_id")
private Course course;
private String grade;
// getters and setters
}
🔹 What happens:
- The table
enrollment
has a composite primary key of(student_id, course_id)
. - Hibernate maps these two columns together as
EnrollmentId
.
🔹 Generated SQL table:
CREATE TABLE enrollment (
student_id BIGINT NOT NULL,
course_id BIGINT NOT NULL,
grade VARCHAR(10),
PRIMARY KEY (student_id, course_id),
FOREIGN KEY (student_id) REFERENCES student(id),
FOREIGN KEY (course_id) REFERENCES course(id)
);
🔹 Approach 2: Using @IdClass
✅ Define a simple class with the same fields as the composite key:
public class EnrollmentId implements Serializable {
private Long studentId;
private Long courseId;
// default constructor, equals, hashCode...
}
@Entity
@IdClass(EnrollmentId.class)
public class Enrollment {
@Id
private Long studentId;
@Id
private Long courseId;
private String grade;
// getters and setters
}
🔹 Key difference:
@IdClass
keeps key fields in the entity itself, while@EmbeddedId
uses a separate embedded object.
When to use which?
✅ Use @EmbeddedId
for cleaner, more object-oriented design → easier to reuse key classes, especially with associations.
✅ Use @IdClass
if you want key fields directly in your entity.
✅ Key takeaway:
To implement composite keys in Hibernate:
- Create an
@Embeddable
class representing the key. - Use
@EmbeddedId
in your entity. - Make sure your key class has proper
equals()
andhashCode()
implementations!