@GeneratedValue Annotation in Spring Boot

In this tutorial, we will learn how to use JPA @GeneratedValue annotation in the Spring boot application.

The JPA @GeneratedValue annotation is used to specify the generation strategy for the value of the primary key.

The @GeneratedValue annotation specifies that the entity identifier value is automatically generated using an identity column, a database sequence, or a table generator. Hibernate supports the @GeneratedValue mapping even for UUID identifiers.

JPA supports 4 types of primary key generation strategies -  AUTOTABLESEQUENCE, or IDENTITY.

1. GenerationType.AUTO

The GenerationType.AUTO is the default generation type and lets the persistence provider choose the generation strategy.

For example, consider we have a Student JPA entity class with GenerationType.AUTO as generation type:
@Entity
@Table(name = "student")
public class Student {

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    @Column(name = "id", updatable = false, nullable = false)
    private Long id;

    @Column(name = "first_name")
    private String firstName;

    @Column(name = "last_name")
    private String lastName;

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

    public Student() {

    }

   // getter and setters
}

2. GenerationType.IDENTITY

The GenerationType.IDENTITY is relies on an auto-incremented database column and lets the database generate a new value with each insert operation. 

For example, consider we have a Student JPA entity class with GenerationType.IDENTITY as a generation type:
@Entity
@Table(name = "student")
public class Student {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "id", updatable = false, nullable = false)
    private Long id;

    @Column(name = "first_name")
    private String firstName;

    @Column(name = "last_name")
    private String lastName;

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

    public Student() {

    }

   // getter and setters
}

3. GenerationType.SEQUENCE

The GenerationType.SEQUENCE is to generate primary key values and uses a database sequence to generate unique values.
For example, consider we have a Student JPA entity class with GenerationType.SEQUENCE as generation type:
@Entity
@Table(name = "student")
public class Student {

    @Id
    @GeneratedValue(strategy = GenerationType.SEQUENCE)
    @Column(name = "id", updatable = false, nullable = false)
    private Long id;

    @Column(name = "first_name")
    private String firstName;

    @Column(name = "last_name")
    private String lastName;

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

    public Student() {

    }

   // getter and setters
}

4.GenerationType.TABLE

The GenerationType.TABLE gets only rarely used nowadays. It simulates a sequence by storing and updating its current value in a database table which requires the use of pessimistic locks that put all transactions into sequential order. This slows down your application, and you should, therefore, prefer the GenerationType.SEQUENCE, if your database supports sequences, which most popular databases do.

For example, consider we have a Student JPA entity class with GenerationType.TABLE as generation type:
@Entity
@Table(name = "student")
public class Student {

    @Id
    @GeneratedValue(strategy = GenerationType.TABLE)
    @Column(name = "id", updatable = false, nullable = false)
    private Long id;

    @Column(name = "first_name")
    private String firstName;

    @Column(name = "last_name")
    private String lastName;

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

    public Student() {

    }

   // getter and setters
}
You can use the @TableGenerator annotation in a similar way as the already explained @SequenceGenerator annotation to specify the database table which Hibernate shall use to simulate the sequence.

@GeneratedValue Annotation in Spring Boot

Let's create a Spring boot project from the scratch and demonstrates the usage of @GeneratedValue annotation.

We will use Spring Data JPA to develop a repository layer and MySQL database at the backend. We will use the Postman client to test the REST APIs. 

1. Create a Spring boot application

Spring Boot provides a web tool called Spring Initializer to bootstrap an application quickly. Just go to https://start.spring.io/ and generate a new spring boot project.

Use the below details in the Spring boot creation:

Project Name: springboot-backend

Project Type: Maven

Choose dependencies: Spring Web, Lombok, Spring Data JPA, and MySQL Driver

Package name: net.javaguides.springboot

Packaging: Jar

Download the Spring Boot project as a zip file, unzip it, and import it into IntelliJ IDEA.

Here is the pom.xml file for your reference:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
	<modelVersion>4.0.0</modelVersion>
	<parent>
		<groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-starter-parent</artifactId>
		<version>2.5.5</version>
		<relativePath/> <!-- lookup parent from repository -->
	</parent>
	<groupId>net.javaguides</groupId>
	<artifactId>springboot-backend</artifactId>
	<version>0.0.1-SNAPSHOT</version>
	<name>springboot-backend</name>
	<description>Demo project for Spring Boot REST APIs</description>
	<properties>
		<java.version>11</java.version>
	</properties>
	<dependencies>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-data-jpa</artifactId>
		</dependency>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-web</artifactId>
		</dependency>

		<dependency>
			<groupId>mysql</groupId>
			<artifactId>mysql-connector-java</artifactId>
			<scope>runtime</scope>
		</dependency>
		<dependency>
			<groupId>org.projectlombok</groupId>
			<artifactId>lombok</artifactId>
			<optional>true</optional>
		</dependency>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-test</artifactId>
			<scope>test</scope>
		</dependency>
	</dependencies>

	<build>
		<plugins>
			<plugin>
				<groupId>org.springframework.boot</groupId>
				<artifactId>spring-boot-maven-plugin</artifactId>
				<configuration>
					<excludes>
						<exclude>
							<groupId>org.projectlombok</groupId>
							<artifactId>lombok</artifactId>
						</exclude>
					</excludes>
				</configuration>
			</plugin>
		</plugins>
	</build>

</project>

2. Create Project or Packaging Structure

You below screenshot to create a project or packaging structure for your Spring boot project:

3. Configure MySQL Database

Since we’re using MySQL as our database, we need to configure the database URLusername, and password so that Spring can establish a connection with the database on startup. Open the src/main/resources/application.properties file and add the following properties to it:
spring.datasource.url=jdbc:mysql://localhost:3306/ems?useSSL=false
spring.datasource.username=root
spring.datasource.password=Mysql@123

spring.jpa.properties.hibernate.dialect = org.hibernate.dialect.MySQL5InnoDBDialect

spring.jpa.hibernate.ddl-auto = update
Don’t forget to change the spring.datasource.username and spring.datasource.password as per your MySQL installation. Also, create a database named ems in MySQL before proceeding to the next section.

You don’t need to create any tables. The tables will automatically be created by Hibernate from the Employee entity that we will define in the next step. This is made possible by the property spring.jpa.hibernate.ddl-auto = update.

4. Create JPA Entity

Go to the model package, create a class named Employee and add the following content to it:
package net.javaguides.springboot.model;

import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;

import javax.persistence.*;

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

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private long id;

    @Column(name = "first_name")
    private String firstName;

    @Column(name = "last_name")
    private String lastName;

    @Column(name = "email_id")
    private String emailId;
}
Note that we have used JPA @GeneratedValue annotation to specify the generation strategy (IDENTITY) for the value of the primary key.

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private long id;

5. Create Spring Data JPA Repository

No, we gonna create a Spring Data JPA repository to talk with the MySQL database.
Go to the repository package, create the following EmployeeRepository interface and add the following content to it:
package net.javaguides.springboot.repository;

import net.javaguides.springboot.model.Employee;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;

public interface EmployeeRepository extends JpaRepository<Employee, Long> {
    // all crud database methods
}

6. Create ResourceNotFoundException Custom Exception

Go to an exception package, create a class named ResourceNotFoundException and add the following content to it:

package net.javaguides.springboot.exception;

import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.ResponseStatus;

@ResponseStatus(value = HttpStatus.NOT_FOUND)
public class ResourceNotFoundException extends RuntimeException{

    public ResourceNotFoundException(String message){
        super(message);
    }
}

7. Creating Spring Boot REST API

Go to the controller package, create a class named EmployeeController and add the following content to it:

package net.javaguides.springboot.controller;

import net.javaguides.springboot.exception.ResourceNotFoundException;
import net.javaguides.springboot.model.Employee;
import net.javaguides.springboot.repository.EmployeeRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;

import java.util.List;

@CrossOrigin("*")
@RestController
@RequestMapping("/api/v1/employees")
public class EmployeeController {

    @Autowired
    private EmployeeRepository employeeRepository;

    // build create employee REST API
    @PostMapping
    public Employee createEmployee(@RequestBody Employee employee) {
        return employeeRepository.save(employee);
    }
}

We have built Create Employee REST API to insert an employee into the database.

Create Employee REST API:

    // build create employee REST API
    @PostMapping
    public Employee createEmployee(@RequestBody Employee employee) {
        return employeeRepository.save(employee);
    }

8. Running the Application

Let's deploy our Spring boot application in a servlet container(embedded tomcat). 
Two ways we can start the standalone Spring boot application. 

9. Test Create Employee REST API using Postman

Let's use Create Employee REST API to insert an employee into the database and then we use Update Employee REST API to update the existing employee information.





Comments