Can JPA entity have a field not mapped to DB column?

By | January 1, 2024

JPA stands for Java Persistence API. It is a specification for managing relational databases in Java applications. JPA is a part of Java EE (Enterprise Edition), and it is used for persisting, retrieving and managing Java objects in a relational database. It provides facilities for developers to interact with the relational database using object-oriented programming principles.

In context with persistence layer, JPA has following two interfaces:

  • EntityManagerFactory
    • It is responsible for creating instances of EntityManager.
  • EntityManager
    • It is the key component in JPA and is used for database operations.
    • EntityManager manages the lifecycle of entities and provides method for CRUD (Create, Read, Update, Delete) operations.

We will be using employee service for this tutorial. You can download the complete source for employee service at GitHub.

Step-by-step implementation

Step 1- Model class: Add @Transient annotation field

In this step, we are first updating our Employee model class and adding two new fields: dateOfBirth: LocalDate and age: integer. We explicitly add a definition for getAge() to calculate the age in real time and a parameterized constructor.

Java
import java.time.LocalDate;
import java.time.Period;

import jakarta.persistence.Entity;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.GenerationType;
import jakarta.persistence.Id;
import jakarta.persistence.Table;
import jakarta.persistence.Transient;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;

@Getter
@Setter
@AllArgsConstructor
@NoArgsConstructor
@Entity
@Table(name = "tbl_emp")
public class Employee {

	@Id
	@GeneratedValue(strategy = GenerationType.IDENTITY)
	protected int id;
	protected String name;
	protected String domain;
	protected String company;
	/**
	 * 1. We are adding two more fields to our Employee class 
	 * 	1.1 dateOfBirth : LocalDate 
	 * 	1.2 age : int
	 * 
	 * 2. We add @Transient annotation over the age and restrict the ORM to persist
	 * the age filed.
	 * 
	 * 3. We have added parameterized constructor to initialize the object
	 * 
	 * 4. We will calculate the age at real-time only and not persist it to DB.
	 * 
	 * @author paulsofts
	 */
	protected LocalDate dateOfBirth;
	@Transient
	protected int age;

	public Employee(int id, String name, String domain, String company, LocalDate dateOfBirth) {
		this.id = id;
		this.name = name;
		this.domain = domain;
		this.company = company;
		this.dateOfBirth = dateOfBirth;
	}

	public int getAge() {
		if (null != dateOfBirth) {
			return Period.between(dateOfBirth, LocalDate.now()).getYears();
		} else {
			return 0;
		}
	}

}

In the above class, we have added the @Transient annotation over the age field. It indicates that the field should not persist in the database when the employee entity persists; instead, it will calculate the age dynamically based on the dateOfBirth field.

Step 2- Test Application

Now, we need to test our application. As we run our application, Hibernate (the implementation of JPA or JPA provider) will automatically create the database table using our Employee entity class.

In the below console log, we can see the tbl_emp has only the ID, name, domain, company, and dateOfBirth fields. The age field is not there as we have restricted the ORM (object relational mapping) to map it to the database column with the help of the @Transient annotation.

Fig 1- Console log

Hibernate automatically creates the tbl_emp using the entity mappings.

console.log
Hibernate: create table tbl_emp (id integer not null auto_increment, company varchar(255), date_of_birth date, domain varchar(255), name varchar(255), primary key (id)) engine=InnoDB

We can also verify using the table created inside the MySQL database.

Fig 2- MySQL database

Below, we have used Potman to test our API to create a Employee.

Fig 3- Create request

We can see that we are not passing the age field in the request body; the application is creating it dynamically and adding it to the response. We can also see in the database table that the age field does not persist.

Fig 4- Database

What is @Transient annotation?

The @Transient annotation in Java, specifically in context to JPA (Java Persistence API), is used to indicate that the field should not persist in the database.

Leave a Reply

Your email address will not be published. Required fields are marked *