"Welcome To Ashok IT" "Spring Boot and MicroServices" Topic : Spring Data JPA - Custom Generator Date : 14/10/2024 (Session - 44) _____________________________________________________________________________________________________________________________ Custom Generator ================ * As of now we worked with some of generators i.e.,AUTO,SEQUENCE,IDENTITY,TABLE. * The above generators always generating the values for primary key columns as integer numbers but sometimes we need generate the primary key column value as alphanumeric combination in such case we need to go for "Custom Generator Development". Example ======= * BatchCode >>>> >>>> ashokit_2023_SBMS_31; * IBM >>>>>>>>>>> IBM_001, IBM_541 etc., * If we want to store value in the above format definetly our primary key column type should be varchar (or) varchar2 in Oracle database (or) varchar in mysql. * If we observe employee Id which contains two parts prefix and suffix (IBM_001); 1) prefix >>>>>>>>>>> IBM >>>>>>>>>>>It is fixed >>>>>>>>>>> constant 2) suffix >>>>>>>>>>> Number(start with some number and increment by some value) >>>>>> sequence Steps for developing the spring data jpa application with custom generator =========================================================================== 1) Create spring boot application with below dependencies * Data JPA Starter * Oracle Driver 2) Create an one entity class using annotations. 3) Create some sequence in database for generating suffix value. 4) Create custom generator class by implementing "IdentifierGenerator" interface. 5) Configure the customerGenerator class at the top of primary key column in Entity class. 6) Create repoistory interface and test for one record generating alphanumeric value for primary key column. Example ======= String welcomeMessage = "Welcome To AshokIT %s at %s some pincode %d"; String finalString = String.format(welcomeMessage,"Hyderabad","Ameerpet",123456789); Example Application =================== Employee.java ============= package com.ashokit.entity; import javax.persistence.Column; import javax.persistence.Entity; import javax.persistence.GeneratedValue; import javax.persistence.Id; import javax.persistence.Table; import org.hibernate.annotations.GenericGenerator; @Entity @Table(name="ashokit_employees") public class Employee { @Id @Column(name="employee_id") @GenericGenerator(name="ashokit_emp_seq", strategy = "com.ashokit.generator.EmployeeGenerator") @GeneratedValue(generator = "ashokit_emp_seq") private String employeeId; @Column(name="employee_name") private String employeeName; @Column(name="employee_salary") private Integer employeeSalary; public String getEmployeeId() { return employeeId; } public void setEmployeeId(String employeeId) { this.employeeId = employeeId; } public String getEmployeeName() { return employeeName; } public void setEmployeeName(String employeeName) { this.employeeName = employeeName; } public Integer getEmployeeSalary() { return employeeSalary; } public void setEmployeeSalary(Integer employeeSalary) { this.employeeSalary = employeeSalary; } @Override public String toString() { return "Employee [employeeId=" + employeeId + ", employeeName=" + employeeName + ", employeeSalary=" + employeeSalary + "]"; } } EmployeeDao.java ================ package com.ashokit.dao; import java.io.Serializable; import org.springframework.data.repository.CrudRepository; import com.ashokit.entity.Employee; public interface EmployeeDao extends CrudRepository { } EmployeeGenerator.java ====================== package com.ashokit.generator; import java.io.Serializable; import java.sql.Connection; import java.sql.ResultSet; import java.sql.Statement; import org.hibernate.HibernateException; import org.hibernate.engine.spi.SharedSessionContractImplementor; import org.hibernate.id.IdentifierGenerator; public class EmployeeGenerator implements IdentifierGenerator{ @Override public Serializable generate(SharedSessionContractImplementor session, Object object) throws HibernateException { String prefix = "ashokit_"; String suffix = ""; try{ Connection con = session.connection(); Statement st = con.createStatement(); ResultSet rs = st.executeQuery("select ashokit_emp_seq.nextval from dual"); if(rs.next()) { suffix = rs.getString(1); } }catch(Exception e) { e.printStackTrace(); System.out.println("Error Generated While generating custom sequence"); } return prefix.concat(suffix); } } /* create sequence ashokit_emp_seq start with 501 increment by 1;*/ Application.java ================ package com.ashokit; 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.EmployeeDao; import com.ashokit.entity.Employee; @SpringBootApplication public class Application implements CommandLineRunner{ @Autowired private EmployeeDao employeeDao; public static void main(String[] args) { SpringApplication.run(Application.class, args); } @Override public void run(String... args) throws Exception { Employee e = new Employee(); e.setEmployeeName("Mahesh"); e.setEmployeeSalary(25000); Employee savedEmployee = employeeDao.save(e); System.out.println("Employee Id::::" + savedEmployee.getEmployeeId()); } } application.properties ====================== spring.datasource.driver-class-name=oracle.jdbc.OracleDriver spring.datasource.url=jdbc:oracle:thin:@localhost:1521:xe spring.datasource.username=system spring.datasource.password=manager spring.jpa.show-sql=true spring.jpa.hibernate.ddl-auto=update spring.jpa.properties.hibernate.format_sql=true OUTPUT ====== . ____ _ __ _ _ /\\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \ ( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \ \\/ ___)| |_)| | | | | || (_| | ) ) ) ) ' |____| .__|_| |_|_| |_\__, | / / / / =========|_|==============|___/=/_/_/_/ [36morg.hibernate.dialect.Dialect  : HHH000400: Using dialect:org.hibernate.dialect.Oracle10gDialect Hibernate: insert into ashokit_employees (employee_name, employee_salary, employee_id) values (?, ?, ?) Employee Id::::ashokit_1110 PagingAndSortingRepoistory Interface ==================================== * It is child Interface of Repoistory Interface. * This interface contains two abstract methods related to pagination & sorting. Pagination ========== * The Process of displaying bulk of records from Database as page by page is called Pagination. * Each page will contains specific no of records. * As business owner he/she will fixing about no of records to be display per page. * In Spring data JPA Pagination can be achieved through "Pageable" Object. * Inorder to get the Pageable object we need to use the below Statement Pageable pg = PageRequest.of(PageNo,PageSize); PageNo Index always Start from "0" Index. PageSize will provide input based on business requirement(5,10,15,20 etc.,) ********************* Example on Pagination ********************* 1000 Records are available In Database Table Dividing the Records into Pages and Each Page will contains 100 Records Total No Of Pages = No Of Records in Database Table / Page per Count Total No Of Pages = 1000 / 100 Total No Of Pages = 10 (0 - 9) Pageable pg = PageRequest.of(0,100); //1-100 Records Pageable pg1 = PageRequest.of(3,100); //400-500 Records Sorting ======= * When we are retriveing records of DB Table either ascending order (or) descending order based on some property. * Sorting will takes place in the following order 1) Special Characters(?,+,',' etc) 2) Numbers 3) UpperCase Alphabets 4) LowerCase Alphabets * In Spring Data JPA Sorting will be achieved through Sort Object. Hierarchy ========= Repoistory(I) >>>>> Parent Interface (Marker Interface) ^ | CrudRepoistory(I) >>>>>> Child Interface(12 Abstract Methods) ^ | PagingAndSortingRepoistory(I) >>>>> Child Interface(2 Abstract Methods) |-> Iterable findAll(Sort Object); >>> This method supports for Sorting Entities based on some Property. |-> Page findAll(Pageable pageable) >>> This Method supports for getting Entities based on Pageable Object