"Welcome To Ashok IT" "Spring Boot and MicroServices" Topic : Spring Data JPA - Generators Date : 11/10/2024 (Session - 43) _____________________________________________________________________________________________________________________________ Today Session ============== *************************** 3) GenerationType.Identity *************************** * In this type of generation Hibernate always generate the value for primary key column based on auto increment feature. * Auto-increment allows a unique number to be generated automatically when a new record is inserted into a table. * This Identity generation can be used for auto increment feature supported databases only. * This Identity generation can't be used for Oracle Database but we can use for following database like MYSQL,SQLServer,PostgreSQL,MSACCESS etc., Example ======= @Id @GeneratedValue(strategy=GenerationType.IDENTITY) private Integer customerId; NOTE ==== * Make sure We need to test this Identity Strategy in MySQL Database Software. * If we are doing the testing with Oracle Database will get error "doesnot support the identity key generation". Example Application =================== package com.ashokit.enities; import javax.persistence.Entity; import javax.persistence.GeneratedValue; import javax.persistence.GenerationType; import javax.persistence.Id; import javax.persistence.Table; @Entity @Table(name="mahesh_banks") public class Bank { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Integer bankId; private String bankName; private String location; public Integer getBankId() { return bankId; } public void setBankId(Integer bankId) { this.bankId = bankId; } public String getBankName() { return bankName; } public void setBankName(String bankName) { this.bankName = bankName; } public String getLocation() { return location; } public void setLocation(String location) { this.location = location; } @Override public String toString() { return "Bank [bankId=" + bankId + ", bankName=" + bankName + ", location=" + location + "]"; } } Steps ===== 1) When we running application defintely will get an error feature not supporting in Oracle Database. 2) To Test this application in smooth manner required MYSQL Database internally will create table with given name create table mahesh_banks(bank_id bigint primary key auto_increment,bank_name varchar(255),location varchar(255)); ************************ 4) GenerationType.TABLE ************************ * In this type of generation Hibernate internally maintains one table to hold the primary keys of all tables in the database. * In this case the generation table is created by Hibernate with name hibernate_sequences and there will be two column in the table i.e.,sequence_name and next_value Example-1: Default Behaviour ============================ @GeneratedValue(strategy=GenerationType.TABLE) 1) Hibernate Internally will create following table i.e.,hibernate_sequences and will create following columns i.e., sequence_name, next_val Hibernate: create table hibernate_sequences (sequence_name varchar2(255 char) not null, next_val number(19,0), primary key (sequence_name)) 2) Hibernate will insert one row information about entity as below Hibernate: insert into hibernate_sequences(sequence_name, next_val) values ('default',0) 3) Hibernate will select value from hibernate_sequences table based on sequence name as below Hibernate: select tbl.next_val from hibernate_sequences tbl where tbl.sequence_name=? for update 4) Hibernate will perform update operation after selecting current value based on sequence name Hibernate: update hibernate_sequences set next_val=? where next_val=? and sequence_name=? 5) Hibernate will perform insert operation on entity Hibernate: insert into mahesh_students (course_fee, course_name, student_name, student_id) values (?, ?, ?, ?) PROBLEM ======= * The entry which is inserted into hibernate_sequence table will be reused for multiple tables that will leads to order problem of primary key column to overcome need to generate entry for each table in hibernate_sequence table (or)our own custom table. Example-2 : We can create our own table name, column name, ========= @GeneratedValue(strategy=GenerationType.TABLE, generator="customers") @TableGenerator( name="customers", table="sequence_store", pkColumnName = "seq_name", valueColumnName = "seq_value", pkColumnValue="customers_seq_id", initialValue=1, allocationSize=1 ) private Integer customerId; 1) Created the table with name i.e.,sequence_store and following two columns i.e.,seq_name, seq_value. 2) Inserted record per table based on primary key column value with initial value sequence_store ************** seq_name seq_value ********* ********** customers_seq_id 1 students_seq_id 1 employees_seq_id 1 products_seq_id 1 3) When We are performing insert operation on particular entity the respective entry seq_value value will be selected and updated the next value as well. Ex: If we are performing insert operation on customer entity object then follow queries will be executed Hibernate: select tbl.seq_value from sequence_store tbl where tbl.seq_name=? for update Hibernate: update sequence_store set seq_value=? where seq_value=? and seq_name=? 4) Performing the Actual Insert Query. Hibernate: insert into mahesh_students (course_fee, course_name, student_name, student_id) values (?, ?, ?,?) =================== Example Application =================== Bike.java ========= package com.ashokit.enities; import javax.persistence.Entity; import javax.persistence.GeneratedValue; import javax.persistence.GenerationType; import javax.persistence.Id; import javax.persistence.Table; import javax.persistence.TableGenerator; @Entity @Table(name = "mahesh_bikes") public class Bike { @Id @GeneratedValue(strategy = GenerationType.TABLE,generator = "bikes") @TableGenerator(name ="bikes", table = "sequence_store", pkColumnName = "seq_name", valueColumnName = "seq_value", pkColumnValue = "bike_id", initialValue = 1, allocationSize = 1) private int bikeId; private String bikeName; private Integer cost; public Integer getBikeId() { return bikeId; } public void setBikeId(Integer bikeId) { this.bikeId = bikeId; } public String getBikeName() { return bikeName; } public void setBikeName(String bikeName) { this.bikeName = bikeName; } public Integer getCost() { return cost; } public void setCost(Integer cost) { this.cost = cost; } @Override public String toString() { return "Bike [bikeId=" + bikeId + ", bikeName=" + bikeName + ", cost=" + cost + "]"; } } Employee.java ============= package com.ashokit.enities; import javax.persistence.Entity; import javax.persistence.GeneratedValue; import javax.persistence.GenerationType; import javax.persistence.Id; import javax.persistence.Table; import javax.persistence.TableGenerator; @Entity @Table(name="mahesh_employees") public class Employee { @Id @GeneratedValue(strategy = GenerationType.TABLE,generator = "employees") @TableGenerator(name ="employees", table = "sequence_store", pkColumnName = "seq_name", valueColumnName = "seq_value", pkColumnValue = "employee_id", initialValue = 1, allocationSize = 1) private Integer employeeId; private String employeeName; public Integer getEmployeeId() { return employeeId; } public void setEmployeeId(Integer employeeId) { this.employeeId = employeeId; } public String getEmployeeName() { return employeeName; } public void setEmployeeName(String employeeName) { this.employeeName = employeeName; } @Override public String toString() { return "Employee [employeeId=" + employeeId + ", employeeName=" + employeeName + "]"; } } EmployeeDao.java ================ package com.ashokit.dao; import org.springframework.data.repository.CrudRepository; import com.ashokit.enities.Employee; public interface EmployeeDao extends CrudRepository { } BikeDao.java ============ package com.ashokit.dao; import org.springframework.data.repository.CrudRepository; import com.ashokit.enities.Bike; public interface BikeDao extends CrudRepository { } Application.java ================ package com.ashokit; import java.util.Arrays; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.CommandLineRunner; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import com.ashokit.dao.BikeDao; import com.ashokit.dao.CustomerDao; import com.ashokit.dao.EmployeeDao; import com.ashokit.dao.ProductDao; import com.ashokit.dao.VehicleDao; import com.ashokit.enities.Bike; import com.ashokit.enities.Employee; import com.ashokit.enities.Product; import com.ashokit.enities.Vehicle; import net.bytebuddy.utility.nullability.UnknownNull; @SpringBootApplication public class Application implements CommandLineRunner{ @Autowired private BikeDao bikeDao; @Autowired private EmployeeDao employeeDao; public static void main(String[] args) { SpringApplication.run(Application.class, args); } @Override public void run(String... args) throws Exception { Employee e1 = new Employee(); e1.setEmployeeName("Mahesh"); //3 & 4 Employee e2 = new Employee(); e2.setEmployeeName("Rajesh"); Iterable savedEmployee = employeeDao.saveAll(Arrays.asList(e1,e2)); savedEmployee.forEach(emp-> System.out.println(emp)); Bike b1 = new Bike(); b1.setBikeName("Access"); //5 && 6 b1.setCost(100000); Bike b2 = new Bike(); b2.setBikeName("Activa"); b2.setCost(200000); Iterable savedBikes = bikeDao.saveAll(Arrays.asList(b1,b2)); savedBikes.forEach(bike -> System.out.println(bike)); } } OUTPUT ====== . ____ _ __ _ _ /\\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \ ( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \ \\/ ___)| |_)| | | | | || (_| | ) ) ) ) ' |____| .__|_| |_|_| |_\__, | / / / / =========|_|==============|___/=/_/_/_/ Hibernate: create table ashokit_students (student_id number(10,0) not null, contact_no varchar2(255 char), eamil_id varchar2 (255 char), name varchar2(255 char), primary key (student_id)) Hibernate: create table sequence_store (seq_name varchar2(255 char) not null, seq_value number(19,0), primary key (seq_name)) Hibernate: insert into sequence_store(seq_name, seq_value) values ('customers_seq_id',1) Hibernate: insert into sequence_store(seq_name, seq_value) values ('students_seq_id',1) Hibernate: create table shopping_customers (customer_id number(10,0) not null, customer_contact_no varchar2(255 char), customer_email varchar2(255 char), customer_location varchar2(255 char), customer_name varchar2(255 char), primary key (customer_id)) Hibernate: select tbl.seq_value from sequence_store tbl where tbl.seq_name=? for update Hibernate: update sequence_store set seq_value=? where seq_value=? and seq_name=? Hibernate: select tbl.seq_value from sequence_store tbl where tbl.seq_name=? for update Hibernate: update sequence_store set seq_value=? where seq_value=? and seq_name=? Hibernate: select tbl.seq_value from sequence_store tbl where tbl.seq_name=? for update Hibernate: update sequence_store set seq_value=? where seq_value=? and seq_name=? Hibernate: select tbl.seq_value from sequence_store tbl where tbl.seq_name=? for update Hibernate: update sequence_store set seq_value=? where seq_value=? and seq_name=? Hibernate: select tbl.seq_value from sequence_store tbl where tbl.seq_name=? for update Hibernate: update sequence_store set seq_value=? where seq_value=? and seq_name=? Hibernate: insert into shopping_customers (customer_contact_no,customer_email,customer_location,customer_name,customer_id) values (?,?,?,?,?) Hibernate: insert into shopping_customers (customer_contact_no,customer_email,customer_location,customer_name,customer_id) values (?,?,?,?,?) Hibernate: insert into shopping_customers (customer_contact_no,customer_email,customer_location,customer_name,customer_id) values (?,?,?,?,?) Hibernate: insert into shopping_customers (customer_contact_no,customer_email,customer_location,customer_name,customer_id) values (?,?,?,?,?) Hibernate: insert into shopping_customers (customer_contact_no,customer_email,customer_location,customer_name,customer_id) values (?,?,?,?,?) ShoppingCustomer [custId=2, name=Mahesh, location=Hyderabad, email=mahesh.ashokit@gmail.com, contactNo=123456789] ShoppingCustomer [custId=3, name=Suresh, location=Pune, email=suresh.ashokit@gmail.com, contactNo=545454454] ShoppingCustomer [custId=4, name=Rajesh, location=Chennai, email=rajesh.ashokit@gmail.com, contactNo=23323232] ShoppingCustomer [custId=5, name=Ramesh, location=Hyderabad, email=ramesh.ashokit@gmail.com, contactNo=121212121] ShoppingCustomer [custId=6, name=Nagesh, location=Hyderabad, email=nagehsh.ashokit@gmail.com, contactNo=3434211123] Hibernate: select tbl.seq_value from sequence_store tbl where tbl.seq_name=? for update Hibernate: update sequence_store set seq_value=? where seq_value=? and seq_name=? Hibernate: select tbl.seq_value from sequence_store tbl where tbl.seq_name=? for update Hibernate: update sequence_store set seq_value=? where seq_value=? and seq_name=? Hibernate: insert into ashokit_students (contact_no,eamil_id,name,student_id) values (?,?,?,?) Hibernate: insert into ashokit_students (contact_no,eamil_id,name,student_id) values (?,?,?,?) Student [studentId=2, studentName=Mahesh, studentEmail=mahesh.ashokit@gmail.com, contactNo=1232323] Student [studentId=3, studentName=Ashok, studentEmail=ashokitschools@gmail.com, contactNo=2323232] **************** sequence_store **************** seq_name seq_value ********* ********** employee_id 5 bike_id 5