Hibernate Composite Primary Keys with @EmbeddedId annotation

Paul Ravvich
Hibernate At the Gates of Mastery
3 min readApr 17, 2024

--

The @EmbeddedId annotation in Java Persistence API (JPA) is used for managing composite primary keys. This article will thoroughly explore its use @EmbeddedId, explaining its functions, advantages, and limitations, illustrated with an example from a project management system.

Hibernate Composite Primary Keys with @EmbeddedId annotation

Hi, this is Paul, and welcome to this article, we explore how to create a Hibernate Entity with composite primary keys with @EmbeddedId annotation.

Purpose of @EmbeddedId

@EmbeddedId is employed to denote a composite primary key that comprises multiple columns, useful in scenarios where a single column does not uniquely identify a record. The annotation indicates that a class will be embedded as an entity's identifier, representing this composite primary key.

How @EmbeddedId Works

To grasp the functionality of @EmbeddedId, let's analyze a practical example involving Project and ProjectMember entities for tables:

CREATE TABLE projects
(
id BIGSERIAL PRIMARY KEY,
name VARCHAR(255) NOT NULL
);

CREATE TABLE project_members
(
user_name VARCHAR(255),
project_id BIGINT,
PRIMARY KEY (user_name, project_id),
FOREIGN KEY (project_id) REFERENCES projects (id)
);

Definition: An @Embeddable class is created including all fields of the composite key. In our case, the class ProjectMemberId includes fields username and projectId.

import jakarta.persistence.Column;
import jakarta.persistence.Embeddable;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;

import java.io.Serializable;

@Getter
@Setter
@NoArgsConstructor
@AllArgsConstructor
@Embeddable
public class ProjectMemberId implements Serializable {
@Column(name = "user_name")
private String username;

@Column(name = "project_id")
private Long projectId;
}

Embedding: In the ProjectMember entity, instead of using a simple @Id, @EmbeddedId is used to embed the ProjectMemberId class. This composite ID is linked to the corresponding fields in the ProjectMember entity.

import jakarta.persistence.*;
import lombok.*;

@Entity
@Getter
@Setter
@Builder
@ToString(exclude = "project")
@NoArgsConstructor
@AllArgsConstructor
@Table(name = "project_members")
public class ProjectMember {
@EmbeddedId
private ProjectMemberId id;

@ManyToOne
@JoinColumn(name = "project_id", insertable = false, updatable = false)
private Project project;
}
  • @EmbeddedId is used to embed ProjectMemberId, linking it to the project through the composite key.
  • @ManyToOne and @JoinColumn define the association with Project, with insertable and updatable set to false to prevent changes through this entity.

Project Entity:

  • Utilizes @Id and @GeneratedValue to manage the uniqueness of each project.
  • Includes the field name and an @OneToMany association with ProjectMember, allowing a project to have multiple members.
import jakarta.persistence.*;
import lombok.*;

import java.util.Set;

@Entity
@Getter
@Setter
@Builder
@ToString(exclude = "members")
@NoArgsConstructor
@AllArgsConstructor
@Table(name = "projects")
public class Project {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "id")
private Long id;

@Column(name = "name", nullable = false)
private String name;

@OneToMany(mappedBy = "project")
private Set<ProjectMember> members;
}

Benefits and Limitations

As noted, using @EmbeddedId offers flexibility in key design and supports database normalization. However, it also adds complexity to the model and can lead to performance issues if not optimally used.

Conclusion

@EmbeddedId is a powerful tool in JPA for managing entities with composite primary keys. Careful schema design and performance testing are recommended to make the most of using @EmbeddedId in your applications.

Thank you for reading until the end. Before you go:

Paul Ravvich

--

--

Paul Ravvich
Hibernate At the Gates of Mastery

Software Engineer with over 10 years of XP. Join me for tips on Programming, System Design, and productivity in tech! New articles every Tuesday and Thursday!