JPA + Hibernate - @EmbeddedId

By Arvind Rai, February 15, 2023
On this page, we will learn to use JPA @EmbeddedId annotation in our Hibernate application.

1. The @EmbeddedId denotes a composite primary key that is an embeddable class. The composite primary key is the combination of database table columns that behave jointly as primary key. We need to create a @Embeddable class whose properties correspond to composite primary key of the database table. The @EmbeddedId is applied to a persistent field, property of an entity class or mapped super class to achieve composite primary key.

2. In an entity, there must be only one @EmbeddedId annotation. The @Id annotation cannot be used in the presence of @EmbeddedId.

3. We can use @AttributeOverride annotation to override column mappings declared within the @Embeddable class.

4. We can use @MapsId annotation with @EmbeddedId annotation to specify a derived primary key.

1. Using @EmbeddedId Annotation

Find an embeddable class NameId with two fields firstName and lastName. Here NameId is representing a composite primary key with columns first_name and last_name in database table.
@Embeddable
public class NameId {
  @Column(name = "first_name")
  private String firstName;
  @Column(name = "last_name")
  private String lastName;
  ------
} 
Now find the entity class that is using NameId as an id. Use @EmbeddedId to make nameId field as an id.
@Entity
@Table(name="person")
public class Person {
  @EmbeddedId
  private NameId nameId;
  @Column(name = "person_city")
  private String city;
  ------
} 
Note: In an entity, @Id cannot be used with @EmbeddedId annotation and @EmbeddedId can be used only one time.

2. Using @EmbeddedId with @AttributeOverride

The @EmbeddedId can be used with @AttributeOverride annotation in an entity when composite primary key column names are different from embeddable class.
The @AttributeOverride annotation is used to override attributes of embeddable class. Our embeddable class NameId represents database table columns as first_name and last_name. In employee table, column names are emp_first_name and emp_last_name. We can use NameId for Employee entity by overriding the attributes as following.
@Entity
@Table(name = "employee")
public class Employee {
	@EmbeddedId
	@AttributeOverrides({ 
	  @AttributeOverride(
		  name = "firstName",
		  column = @Column(name = "emp_first_name")
	  ),
	  @AttributeOverride(
		  name = "lastName",
		  column = @Column(name = "emp_last_name")
	  ) 
	})
	private NameId nameId;
        ------
} 


3. Complete Example

1. Technologies Used
1. Java 19
2. Hibernate 6
3. Jakarta Persistence API 3
4. MySQL 5.5

2. MySQL Database
CREATE TABLE `person` (
	`first_name` VARCHAR(50) NOT NULL,
	`last_name` VARCHAR(50) NOT NULL,
	`person_city` VARCHAR(50) NOT NULL,
	`landline_num` VARCHAR(20) NOT NULL,
	`mobile_num` VARCHAR(20) NOT NULL,
	PRIMARY KEY (`first_name`, `last_name`)
)

CREATE TABLE `employee` (
	`emp_first_name` VARCHAR(50) NOT NULL,
	`emp_last_name` VARCHAR(50) NOT NULL,
	`emp_company` VARCHAR(50) NOT NULL,
	`landline_num` VARCHAR(50) NOT NULL,
	`mobile_num` VARCHAR(50) NOT NULL,
	PRIMARY KEY (`emp_first_name`, `emp_last_name`)
) 
3. pom.xml
<dependencies>
	<dependency>
		<groupId>org.hibernate</groupId>
		<artifactId>hibernate-core</artifactId>
		<version>6.1.6.Final</version>
	</dependency>
	<dependency>
		<groupId>org.hibernate</groupId>
		<artifactId>hibernate-entitymanager</artifactId>
		<version>6.0.0.Alpha7</version>
	</dependency>		
	<dependency>
		<groupId>mysql</groupId>
		<artifactId>mysql-connector-java</artifactId>
		<version>8.0.32</version>
	</dependency>
</dependencies> 
4. persistence.xml
<?xml version="1.0" encoding="UTF-8"?>
<persistence xmlns="https://jakarta.ee/xml/ns/persistence"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="https://jakarta.ee/xml/ns/persistence
          https://jakarta.ee/xml/ns/persistence/persistence_3_0.xsd"
	version="3.0">
	<persistence-unit name="com.concretepage">
		<description>Procedure Demo</description>
		<provider>org.hibernate.jpa.HibernatePersistenceProvider</provider>
		<properties>
			<property name="hibernate.dialect"
				value="org.hibernate.dialect.MySQLDialect" />
			<property name="jakarta.persistence.jdbc.driver"
				value="com.mysql.cj.jdbc.Driver" />
			<property name="jakarta.persistence.jdbc.url"
				value="jdbc:mysql://localhost/concretepage" />
			<property name="jakarta.persistence.jdbc.user" value="root" />
			<property name="jakarta.persistence.jdbc.password"
				value="cp" />
		</properties>
	</persistence-unit>
</persistence> 
5. Java Code
HibernateUtil.java
package com.concretepage.util;
import jakarta.persistence.EntityManager;
import jakarta.persistence.EntityManagerFactory;
import jakarta.persistence.Persistence;

public class HibernateUtil {
 	private static final EntityManagerFactory emFactory;
	static {
		   emFactory = Persistence.createEntityManagerFactory("com.concretepage");
	}
	public static EntityManager getEntityManager(){
		return emFactory.createEntityManager();
	}
}
NameId.java
package com.concretepage.entity;
import jakarta.persistence.Column;
import jakarta.persistence.Embeddable;

@Embeddable
public class NameId {
  @Column(name = "first_name")
  private String firstName;
  @Column(name = "last_name")
  private String lastName;
  public NameId() {}
  public NameId(String firstName, String lastName) {
	this.firstName = firstName;
	this.lastName = lastName;
  }
  // setters and getters
} 
ContactNumber.java
package com.concretepage.entity;
import jakarta.persistence.Column;
import jakarta.persistence.Embeddable;

@Embeddable
public class ContactNumber {
  @Column(name = "landline_num")
  private String landline;
  @Column(name = "mobile_num")
  private String mobile;
  public ContactNumber() {}
  public ContactNumber(String landline, String mobile) {
	this.landline = landline;
	this.mobile = mobile;
  }
  // setters and getters
} 
Person.java
package com.concretepage.entity;
import jakarta.persistence.Column;
import jakarta.persistence.Embedded;
import jakarta.persistence.EmbeddedId;
import jakarta.persistence.Entity;
import jakarta.persistence.Table;

@Entity
@Table(name="person")
public class Person {
	@EmbeddedId
	private NameId nameId;
	@Embedded
	private ContactNumber contactNum;
	@Column(name = "person_city")
	private String city;
	
	public Person() {}
	public Person(NameId nameId, ContactNumber contactNum, String city) {
		this.nameId = nameId;
		this.contactNum = contactNum;
		this.city = city;
	}
        // setters and getters	
} 
Employee.java
package com.concretepage.entity;
import jakarta.persistence.AttributeOverride;
import jakarta.persistence.AttributeOverrides;
import jakarta.persistence.Column;
import jakarta.persistence.Embedded;
import jakarta.persistence.EmbeddedId;
import jakarta.persistence.Entity;
import jakarta.persistence.Table;

@Entity
@Table(name = "employee")
public class Employee {
	@EmbeddedId
	@AttributeOverrides({ 
	  @AttributeOverride(
		  name = "firstName",
		  column = @Column(name = "emp_first_name")
	  ),
	  @AttributeOverride(
		  name = "lastName",
		  column = @Column(name = "emp_last_name")
	  ) 
	})
	private NameId nameId;
	@Embedded
	private ContactNumber contactNum;
	@Column(name="emp_company")
        private String company;
   
	public Employee() {}
	public Employee(NameId nameId, ContactNumber contactNum, String company) {
		this.nameId = nameId;
		this.contactNum = contactNum;
		this.company = company;
	}
        // setters and getters	
} 
Main.java
package com.concretepage;
import com.concretepage.entity.ContactNumber;
import com.concretepage.entity.Employee;
import com.concretepage.entity.NameId;
import com.concretepage.entity.Person;
import com.concretepage.util.HibernateUtil;
import jakarta.persistence.EntityManager;

public class Main {
  public static void main(String[] args) {
	EntityManager entityManager = HibernateUtil.getEntityManager();
	entityManager.getTransaction().begin();
	
	NameId personName = new NameId("Mahesh", "Sharma");
	ContactNumber personContactNum = new ContactNumber("121212", "3232323232");
	Person person = new Person(personName, personContactNum, "Bangalore");
	
	NameId empName = new NameId("Ajeet", "Bharati");
	ContactNumber empContactNum = new ContactNumber("212121", "4343434343");
	Employee employee = new Employee(empName, empContactNum, "ABC");
	
	entityManager.persist(person);
	entityManager.persist(employee);
	
	entityManager.getTransaction().commit();
	entityManager.close();
  }
} 
Find the print screen of the database output.
JPA + Hibernate - @EmbeddedId Example

Reference

Download Source Code

POSTED BY
ARVIND RAI
ARVIND RAI
LEARN MORE












©2024 concretepage.com | Privacy Policy | Contact Us