Download as docx, pdf, or txt
Download as docx, pdf, or txt
You are on page 1of 45

Chapter-02

Spring Boot Data JPA


Before Spring Framework or Spring boot came into market industry follows below
approach to interact Java to DB.
I/O Stream
1. Java App <==============> Files

JDBC+SQL
2. Java App <==============> RDBMS DB s/w
ORM
3. Java App <==============> RDBMS DB s/w

=====
JDBC
=====
- The JDBC API allows programmers and Java applications to interact with
databases.
- JDBC is a specification used for developing database applications with java
programming.
- JDBC provides interfaces like Connection, Statement, ResultSet...etc. and
those interfaces are implemented by database vendors like MySQL, Oracle…
etc.
- JDBC is Database independent API. If we want to move one db to another
db, Java code is same. Properties needs to be modified (driver class, url,
user, password) Some SQL Queries need to be modified.
JDBC Limitations:
- JDBC codes need SQL queries to develop persistence logic, 30% to 40% SQL
queries are DB dependent. So JDBC is DB dependent persistence logic.
- Boiler plate code problem (loading driver class, JDBC connection, create
statement, closing JDBC objects, exception handling… etc. repeat in multiple
part of the project.
- SQL Query need to be given by programmer.
- Schema creation, modification must be done by programmer.
Ex: table creation, alter table…
Chapter-02
Spring Boot Data JPA
- For all problem its throws only SQL exception with different messages i.e.
programmer cannot identify the problem clearly.
- SQLException are Checked Exception so, programmer will force to handle
exception which may create exception propagation issues.

To overcome those problems, we will use ORM concept.


===============================
ORM [Object relational Model]:
===============================

- Object-Relational Mapping (ORM) is the process of converting Java objects


to database tables
- The process of mapping java classes with DD tables and class properties
with DB columns and representing the object of java class with row of the
DB tables is called ORM.
- Synchronization between objects and DB table rows means if we modification on
table row data that also reflect java object and vice-versa.
- In our mapping all persistence operations done by objects. Our object-based
persistence logic will same for all DB s/w. So, ORM is DB independent framework.
- ORM internally use JDBC and SQL queries.

Note: Vice-versa means reverse also possible.

 One class is equals to one table.


 One variable is equals to one column.
 One object is equals to one row/record.
Chapter-02
Spring Boot Data JPA
Entity Class/Model class/Persistence class:
- The class which is mapped to database table. Where class name mapped to
table name and variables name mapped to table column name.
List of ORM Framework
1. Hibernate from red hat
2. Link from eclipse
3. iBatis from Apache
4. toplink from Oracle
5. OJB from Apache

JPA [Java Persistency API]:


- JPA is Object Oriented Programming for database Operations.
- JPA is a specification (with some rules, containing interfaces) given by
Sun/Oracle that defines how to persist data in Java applications.
- We do not define any SQL Query. We perform operations over Objects that
effects Database tables.
Q) When should we use JDBC and where should we use ORM(Hibernate)?
Answer:
- If app gets huge amount of data batch by batch for processing like census
information, survey information, marketing information then using ORM is
problematic because to represent 1 record for 1 object required… suppose batch
contain 80k records to process then 80k objects is required at a time which may
lead application crash. Because java object creation is very costly.so more object
means more memory, more CPU required.
But in JDBC for batch processing where single ResultSet object will be created to
process huge no. of records.
So, for batch processing JDBC is good.
- If app is getting little amount of data to process (30 to 40 records at a time) then
prefer ORM because we can enjoy other features of ORM like DB portability,
versioning, caching, locking, timestamping… etc.
Chapter-02
Spring Boot Data JPA
Q) What are differences between JPA and ORM?
Answer:
- JPA is theory or planning/Specification (provides set of rules guidelines to
develop Objects persistence logic.
- ORM is real implementation of JPA rules and guidelines. All ORM software’s
(like hibernate) are develop based on JPA specification rules and guidelines.
Hibernate programming means writing ORM logics in hibernate style.
Hibernate with JPA programming means writing ORM logics in JPA-hibernate
style.

==========================================================
In Spring Framework, before arrival of Spring Data to the market
==========================================================

Spring JDBC
- Spring Framework Provide Spring JDBC for SQL DB software based on Plain
JDBC.

- Spring JDBC module provides the abstraction on plain JDBC code by avoid
boiler plate code (Taking cares of common logic internally). Instead of
writing Plain JDBC code prefer to writing Spring JDBC code.

Plain JDBC code Spring JDBC code

Spring ORM
- Spring framework provide Object based persistence logic Module Spring ORM.
Chapter-02
Spring Boot Data JPA
- Plain ORM framework (Hibernate) code contains lots of common logics. So, Spring
ORM avoid boiler plate code and provide abstraction on ORM and simplify ORM
persistence logic development with the support of HibernateTemplate classes.

Plain ORM code Spring ORM with Hibernate

Note: Before Spring Data there is no module in Spring framework to interact with NoSQL
based DB software. And to interact with SQL DB, Spring provide a separate module
(Spring JDBC), for ORM a separate module (Spring ORM) is given. That is no uniformity
and unified model for interacting with SQL and NoSQL DB Software.
Spring Data module is given Uniformity and unified model to interact both SQL DB
software (JDBC, ORM style) and NoSQL DB software.
Spring Data is the main Module of Spring Framework. Spring Data having 30+ sub
module like-
1. Spring Data JDBC
2. Spring Data JPA
3. Spring Data MongoDB
4. Spring Data Cassandra
5. ….
6. … etc.

Spring Data JDBC and JPA with Hibernate – No logics only create our own interface that
extends Spring data predefine Repository like CrudRepository,
PagingAndSortingRepository… etc. that provides readymade methods.

Note: Spring/Spring boot internally generates implemented class as in memory proxy


for above interfaces.
=========================================================
Limitation with Plain JDBC/Spring JDBC, ORM/Spring ORM
=========================================================
Chapter-02
Spring Boot Data JPA
- If our project contains 500 DB tables if we are performing 6 to 10 persistence
operation (CRUD Operation) on each DB tables then we should 500*6 = 3000
persistence logics are required and also, we need to 500 DAO interfaces, 500 DAO
implemented classes.
So, this is not recommended way. To avoid this type of boiler plate code we can use
Spring Framework Introduce Spring Data JPA module.
============================
Advantages with Spring Data JPA
============================
- If our project contains 500 DB tables if we are performing 6 to 10 persistence
operation (CRUD Operation) on each DB tables then we just need to take 500 user
define interfaces that’s extending Spring Data JPA provided repositories like
CrudRepository, PagingAndSortingRepository and provides some readymade
methods. Spring or Spring Boot will generate the 500 implementation classes as
InMemory Proxy class that internally uses Hibernate codes.
==============
Benefits of ORM
==============
- Schema creation, modification done Dynamically.
Ex: table creation, alter table…
- The select operation can get the results in desired format like int, float, List and
etc.
- Generators are given to generate PK column value dynamically.
- Good Transaction management support.
- Versioning and Timestamp support.
 Versioning – keeps track of how many times the object/records are
modified through ORM.
 Timestamp – keeps track when the object/record is lastly accessed and
updated.
- The entity classes we developed using JPA annotation that’s are DB software and
ORM framework independent.
- JPQL for Custom Queries [Java Persistency Query Language] which is Database
Independent.

Spring Data Repositories Hierarchy


Chapter-02
Spring Boot Data JPA

1. “org.springframework.data.repository.Repository<T, ID>” is a Marker


Interface. It is Parent interface for all Spring Data Repositories.
2. Frist 3 repositories are common for all Spring Data sub-modules interfaces
like JpaRepository for hibernate with JPA, MongoRepository for NoSQL DB…
etc.
3. In Repository<T, ID>
 T indicate Entity class Name (Internally generate hibernate code in
proxy class by using Entity class object.
 ID @Id property type, the property type that points to pk column of
the DB Table.
Note: Spring or Spring boot generate implemented classes of our Repository
interfaces by using In memory proxy (Dynamic Proxy) classes when our Repository
interface extending from org.springframework.data.repository.Repository<T, ID>
either directly or indirectly.
Dynamic Proxy: A class created at runtime and object also
We can develop Application using Spring data JPA in below approaches.
1. Using Spring driven XML configurations
2. Using Spring driven XML and Annotation configuration.
3. ***Using Spring Boot (Spring boot Data JPA)

Spring Boot Data JPA


Chapter-02
Spring Boot Data JPA
- Spring data JPA is one sub module of Spring data module used to develop
persistence layer.
- It is internally use Hibernate with JPA code.
JpaRepository:
- It is a pre-define interface that provides Spring framework.
- JpaRepository Provides some readymade methods to perform commonly
used persistence’s operations.
======================================
Step to develop Spring Boot Data JPA App
======================================
1. Create Spring Boot Starter Project with App Name: MyDataJpaApp
2. Add dependencies:
 Spring Data JPA
 DB specific driver (Oracle Driver)
3. In application.properties:
 For Database configuration
 spring.datasource.driver-class-name=oracle.jdbc.OracleDriver
 spring.datasource.url=jdbc:oracle:thin:@localhost:1521:orcl
 spring.datasource.username=system
 spring.datasource.password=Oracle
 JPA-Hibernate Configurations
 spring.jpa.database-platform= org.hibernate.dialect.OracleDialect
 spring.jpa.properties.format_sql = true
 spring.jpa.show-sql=true
 spring.jpa.hibernate.ddl-auto=update
4. Define one Entity class that map with DB table using hibernate annotation
5. Create repository package
 In this package, we need to Define one interface that extends any interface
like CrudRepository, PagingAndSortingRepository or JpaRepository<T, ID>.
6. Define one service package
 In this package, define ________service class and perform persistence
operations.

===============================
JPA-hibernate configs properties
Chapter-02
Spring Boot Data JPA
===============================

1. spring.jpa.database-platform= org.hibernate.dialect.OracleDialect
 define dialect
 For Oracle – OracleDialect means for all version
- OracleVersionDialect means for specific dialect.
 It is optional property
Dialect: Dialect is the component which is internally used by hibernate to generate SQL
queries based on database and Vesion. Dialect will change version to version and DB to
DB.
2. spring.jpa.properties.format_sql = true
 Show SQL queries as SQL format
3. Spring.jpa.show-sql=true
 Hibernate internally generate SQL queries using the specified SQL dialect.
To see those generated queries as log message we need to use this above
property.
4. spring.jpa.hibernate.ddl.auto=update/ create/ create-drop/ validate
 create: always create new DB table. If the DB table is already present then
it deletes the DB table and create new DB Table.
 create-drop: create new table when application start and when we stop
application delete table. Use case in testing environment, UAT
environment.
 validate: check DB is already available according to Entity class or not if not
then exception will raised.

 update: Create new table if not exist, else use same table if table is
available according to Entity class. If entity class is modified then this
modification will affect to the DB table.

==================================
Basic JPA annotation for O-R mapping
Chapter-02
Spring Boot Data JPA
==================================
1. @Entity (mandatory): Maps java class with table and variables with columns.
2. @Id (mandatory): Indicates Primary Key column
3. @Table (Optional): If we did not specify then class name is taken as table name.
4. @Column (Optional): If we did not specify then variable name is taken as column
name.
5. @GeneratedValue: It is used to generate Primary Key value only on save.
6. @GeneratedValue (strategy=GenerationType.TypeName)
 IDENTITY for MYSQL
 SEQUENCE for ORACLE
 AUTO for default BASED which DB we used.
7. @SequenceGenerator(name= “gen1”, initialValue=1000, allocationaSize=1
sequenceName = “empId_SEQ”)
======================
CrudRespository<T, ID>
======================

- CrudRepository<T, ID>(I) provides 12 readymade methods for Basic CRUD


Operations.

===============================
CrudRespository<T, ID> Methods
===============================
1. E save(E e)
 This method takes one entity object and internally generate (JDBC+SQL) query to
insert this object as a record into a DB and return same object with generated PK
ID.
 First it will check this entity already present inside DB table or not based on ID
“SELECT * FROM TABLE WHERE PK_COL = VAL”
 If record is not present then internally execute hibernate persist() method that is
used to insert a new record.
 Else record is already present then execute hibernate merge() method that is
used for update operation.

Example:
Employee emp = repo.save(employee);
emp.getEmpName();
emp.getEmpId();
2. saveAll (Iterable<s> entities);
Chapter-02
Spring Boot Data JPA
 This method takes multiple objects at a time as a Collection type(List,
Set…) and performs same operation like save() method.
Examples:
1. Product p1 = new Product(10,"P2",300.0);
2. Product p2 = new Product(11,"P3",400.0);
3. Product p3 = new Product(12,"P4",500.0);
4.
5. List<Product> list = new ArrayList();
6. list.add(p1);
7. list.add(p2);
8. list.add(p3);
9. Iterable<Product> product = repo.saveAll(list);
(or)
1. Iterable<Product> product = repo.saveAll(Arrays.asList(p1,p2,p3));

1. Iterable<Product> product = repo.saveAll(List.of(p1,p2,p3));

3. long count()
 This method returns total no. of rows/records present in DB table.
Example:
long noOfProduct = productRepo.count();

4. boolean existsById(id)
Chapter-02
Spring Boot Data JPA
 It will check a particular record/row present in Db table or not based on
give id. If present then true, else false.
Example:
Boolean isProductAvailable = repo.existsById(11);
5. Iterable<T> findAll()
 Get all records from DB table by generating and executing select query
without applying any conditions.
 Internal SQL Query: select * from product;
Example:
1. Iterable<Product> data = repo.findAll();
2. //JDK 1.5 forEach Loop
3. for(Product pob:data) {
4. System.out.println(pob);
5. }

1. //JDK 1.8 Default method + Lambda Expression


2. data.forEach(ob-> System.out.println(ob));

1. //JDK 1.8 Default method + static method references


2. data.forEach(System.out::println);

6. Iterable<T> findAllById(Iterable<ID> id)


 It will take list of Ids as input param and return list of records based on
these ids.
 Internal SQL Query: select * from product where pid in (11,23,45,67);
Example:
1. Iterable<Product> list = repo.findAllById(Arrays.asList(11,22,45,56,85));
2. list.forEach(System.out::println);

1. Iterable<Product> list = repo.findAllById(List.of(11,22,45,56,85));


2. list.forEach(System.out::println);

1. List<Integer> list = new ArrayList();


2. list.add(101);
3. list.add(102);
4. Iterable<Product> lists = repo.findAllById(list);
7. Optional<T> findById(id)
Chapter-02
Spring Boot Data JPA
 This method is used to fetch one row/record data from DB based on PK.
 This method returns one record as Optional<T> object where T is an Entity
class name.
 Internal SQL Query: select * from product where id=10;
Optional<T>
- Optional is a class introduced in JDK 1.8v. it is contained an object as a container
object. It is used to avoid “NullPointerException” by using methods like
“isPresent()” and “get()”.
Example:
1. // fetch one row based on id
2. Optional<Product> opt = repo.findById(11);
3. if (opt.isPresent()) {
4. Product p = opt.get();
5. System.out.println(p);
6. } else {
7. System.out.println("DATA NOT FOUND");
8. }

(Or)
Using “orElseThrow()” method:

1. Product p = repo.findById(11)
2. .orElseThrow(() -> new ProductNotFoundException("NOT EXIST"));

This line, if record is found the return entity object otherwise throw our customized
PNFE.

Using orElse() method:

1. Product p = repo.findById(11).orElse(new Product());

This line, if record is available returns entity object data otherwise return empty Product
object.

8. void delete(T entity)


Chapter-02
Spring Boot Data JPA
 It is taking one object as input and try to delete that object/record.
Examples:
Option-01:
1. public String removeProductById(Integer pid){
2. Product product = repo.findById(pid)
3. .orElseThrow(()-> new PNFException(“Product Not Found”));
4. repo.delete(product);
5. return “Product Deleted”;
6. }

Option-02:
1. public String removeProductById(Integer pid){
2. Optional<Product> product = repo.findById(pid);
3. if(product.isPresent()){
4. repo.delete(product);
5. return “Product Deleted”;
6. }else{
7. return “Product not found”
8. }
9.}

Option-03
1. repo.delete(repo.findById(77)
2. .orElseThrow(()->new ProductNFException(“Product not found”)));

Option-04
1. Public String removeProduct(Product product){
2. repo.delete(product);
3. Return “Product deleted”;
4. }

9. void deleteById(ID)
Chapter-02
Spring Boot Data JPA
 This method is used to delete one record based on ID given. It internally calls
delete method. First check object is present or not using findById if present call
delete(obj) method else throw exception like: EmptyResultDataAccessException.
Example:

1. Public String removeProductById(Integer pid){


2. repo.deleteById(pid);
3. return “Product ” + pid + “ deleted”;
4. }

10. void deleteAll()


 this method fetching all rows data using findAll() method passing one by
one object to delete(obj) method.
Example:
1. public String removeAllProduct(){
2. long count = repo.count();
3. if(count!=0){
4. repo.deleteAll();
5. }
6. return count + “ no. of records are deleted”;
7. }

11. void deleteAllById(idsAsList)


 This method takes list of ids and delete one by one record based on the
given ids by using deleteAll(id) method in a loop.
Example:
1. repo.deleteAllById(Arrays.asList(10,11));

12. void deleteAll(listOfObjects)


Chapter-02
Spring Boot Data JPA
=================================
PagingAndSortingRepository<T, ID>
=================================
- PagingAndSortingRepossitory is a child interface of CrudRepository interface that
is given by Spring Boot Data JPA. It is used to retrieve records by applying sorting
and Pagination methodology.
- This interface given two methods.
1) Iterable<T> findAll(Sort sort)
2) Iterable<T> findAll(Pageable pageable)
-----------
Sorting
-----------
- PagingAndSortingRepository<T, ID> interface given findAll(Sort sort) method for
sorting DB table records.
- SQL Query like: select * from employee order by esal desc;
Method: Iterable<T> findAll(Sort sort)
Sort is a class having by() as static method which is overloaded method.
1. by(String... properties)
 we can pass multiple columns for sorting (default order ASC)
 we can change default order by using methods -
 <Sort> ascending();
 <Sort> descending();
Example:
I. Create Sorting object by passing columns as a parameter
II. Pass Sort object to findAll() as parameter input
1. Sort d = Sort.by("empId","empName").descending();
2. Iterable<Employee> sort = repo.findAll(d);
3. sort.forEach(System.out::println);

(Or)
1. Iterable<Employee> sortEmp =repo.findAll(Sort.by(“empId”).ascending())
2. .forEach(System.out::println();
Chapter-02
Spring Boot Data JPA
2. by(Direction, String... properties) // var – arg method
 Pass direction which order we want to sort and based on how many columns we
want.
 Direction is Enum having two value ASC and DESC.

Example:
1. Sort s = Sort.by(Direction.DESC,"empId");
2. repo.findAll(s).forEach(System.out::println);

(Or)
1. Iterable<Employee> sortEmp
2. = repo.findAll(Sort.by(Direction.ASC, “empId”, “empJoinDate”);
3. for(Employee emp:sortEmp){
4. System.out.println(emp);
5. }

3. by(Order...)
 This method is a var-arg method, used for mixing sorting order like one column
sort based on ascending order and one column based on descending order.
 SQL query: select * from employee order by esal desc, dept asc;
 Order is static inner class present inside Sort class and having static methods like-
 <Order> asc(columnName)
 <Order> desc(columnName)
 <Order> by(columnName) // default sorting

Example:
1. Sort sort = Sort.by(Order.asc("empDept"),Order.desc("empSalary"))
2. repo.findAll(sort).forEach(System.out::println);

(Or)
1. repo.findAll(Sort.by(Order.asc("empDept"),Order.desc("empSalary")))
2. .forEach(System.out::println);

Note: First it will sort based on “empDept” column then sort based on “empSalary”
column if multiple “empSalary” column values are same.
Chapter-02
Spring Boot Data JPA
---------------
Pagination
---------------
- The process of displaying huge no. of records page by page is called pagination.
- Using findAll() method get all rows from DB table. In case of large/huge number
of records/rows display at client side may not good. That’s why Spring data JPA
provide Pagination Concept.
- PagingAndSortingRepository<T, ID> interface given findAll(Pageable pageable)
method for displaying data page by page.

Method: Page<T> findAll(Pageable pageable)


- This method take Pageable object as a input and return Page<T>(I) object that
contain data and metadata like getContent(), getTotalPages(), isLast(), isFirst(),
isEmpty(), hasNext, getSize()… etc.

To create Pageable object


 Pageable pageable = PageRequest.of(pageNo, pageSize)
 PageRequest is a implementation class of Pageable interface having static
method of() that return Pageable object.
 of() method take two inputs pageNo and pageSize.
 pageNo (0 Based): Represent page no.
 pageSize: Represent, per page or each page how many rows or records we
want. Example: pageSize 3 means per page = 3 records.
Example:
If a DB table having 20 records. We pass of() method parameters as pageNo=1 and
pageSize = 6. Then total page is 4 (0 to 3) these are 6,6,6,2. And pageNo=1 is 7 to 12
records/rows means 2nd page.
 Page<T> page = repo.findAll(pageable);
 Pass Pageable object to the findAll() method as a parameter and return
this method Page object.
 By using Page object we can access data and meta data info.
Chapter-02
Spring Boot Data JPA
Example:

1. Pageable pageable = PageRequest.of(pageNumber, pageSize);


2. Page<Employee> pageData = repo.findAll(pageable);
3. List<Employee> records= pageData.getContent();
4. records.forEach(System.out::println);

(Or)
1. PageRequest pageable = PageRequest.of(pageNumber, pageSize);
2. Page<Employee> pageData = repo.findAll(pageable);
3. List<Employee> records= pageData.getContent();
4. records.forEach(System.out::println);

Page object metadata


Sno Name
01 A
02 B
03 C
04 D
05 E
06 F
07 G
08 H
09 I
10 J

PageRequest.of(1,3)
1. pageData.isEmpty(); // false
2. pageData.isLast(); // false
3. pageData.isFirst(); // false
4. pageData.hasNext(); // true
5. pageData.hasPrevious(); // true
6. pageData.getTotalElements(); //total records 10
7. pageData.getTotalPages(); // 4
8. pageData.getSize(); // page size or how many row per page 3
9. pageData.hasContent(); //get second page 3 records as List<Employee>(D,E,F)
10. pageData.getNumber(); // current page number 1
11. pageData.getNumberOfElements(); //current page how many rows are present 3.

We can create Pageable object with Sorting also


Example:
1. Sort sort = Sort.by(“empId”).ascending();
2. Pageable pageable = PageRequest.of(pageNo, pageSize, sort)

Note: “@PageableDefault(page=0,size=4) Pageable pageable” is used to set default


values for Application.
Chapter-02
Spring Boot Data JPA
===================
JpaRepository<T, ID>
===================
- CrudRespository and PagingAndSortingRepository are common repositories for
both SQL s/w and No-SQL s/w. if we are using these interfaces methods, we need
not to change our code in service layer if we want to move SQL s/w to No SQL
s/w.
- JpaRepository is a child interface of PagingAndSortingRepository and
CrudRepository (Indirectly) interfaces. JpaRepository is dedicated for SQL s/w
only.
- Most of the methods available in JpaRepository are also present in those parent
repositories. But JpaRepository Interfaces methods are work in JPA (hibernate)
implementation style.
- By using JpaRepository interface we can write our custom persistence logic. These
can be used for SELECT, DELETE and UPDATE but INSERT operation not supported.

 Finder/findBy method for select operations


 @Query methods (To use JPQL, SQL queries for select operation)
 @Query + @Modifying methods for non-select query.
 Query By Example used for dynamic filter data

Some differences between CrudRepository Methods and CrudRepository Methods


CrudRepository Methods JpaRepository Methods
1. saveAll() and findAll() methods return 1. saveAll() and findAll() methods return
type Iterable<T> Collection. type List<T> Collection
2. findAll() method do not takes Example 2. findAll() method takes Example obj,
obj, Sort obj as a method arguments Sort obj as a method arguments
3. findById(-) return type Optional<T> 3. getById(-) return type <Entity>
4. deleteXXX(-) methods perform bulk 4. deleteXXX(-) methods perform bulk
operation by generating multiple operation by single delete SQL query
delete queries. through Batch Processing.
5. These methods are common for SQL 5. These methods are only for SQL DB
and non-SQL DB

Note: JpaRepository is bit known for performing delete operations through batch
processing. It is bit faster.
Chapter-02
Spring Boot Data JPA
-------------------------
Query by Example
------------------------
- It is used to prepare dynamic query based on data available in entity class object.
- Means if we want to search record based on pk or non pk column/columns like
search patient where name = abc and id =198.
- SQL Query: select * from patient_details where pid = 198 and pname= “abc”;
- In CrudRepository and PagingAndSortingRepository interfaces, there is no
method which full fill this type of requirement. But JpaRepository interface
provide findAll(Example<T>) method.

Coding:
-----------
1. Patient p = new Patient();
2. p.setPid(198);
3. p.setPname(“abc”);
4. Example example = Example.of(p);
5. Repo.findAll(example).forEach(System.out::println);

==================
finder/findBy method
==================
- Define abstract method in repository interface by following certain naming rules.

- We can perform only SELECT operations and non-select operation (UPDATE,


DELETE, INSERT) are not possible.

- The select operation which are not possible using findXXX() methods of pre-
define Interfaces, we can developed these kinds of select operation by using
finder/findBy method.

Syntax:
<return type> findBy <class PropertyName> <conditions> (parameter…)

Note: The table name or column names are not case sensitive but column value is case-
sensitive.

The finder method can be used for


Chapter-02
Spring Boot Data JPA
1. Selection: Retrieving all columns data from Database table completely or partially
based on condition.
 SQL >> SELECT * FROM movie_dtls
 SQL >> SELECT * FROM movie_dtls WHERE mid = 10

2. Projection: Retrieving specific columns data from Database table known as


"Projection".
 SQL >> SELECT mid, mname, year FROM movie_dtls
SELECT Query Return Type (based on Row/record)
 For single record – Optional<T>
 For multiple records – List<T>

SELECT QUERY (finder, @Query method) return type (based on columns)


 List<T>: For fetching all columns values (Selection)
 List<DataType>: For fetching only 1 column value (projection)
 List<Object[]>: For fetching 1 or 2 column values but not all columns (projection)

Getting Multiple records using Selection Operations


1. Public interface IProductRepository extends JpaRepository<Product, Integer>{
2. //SQL: SELECT * FROM BOOK WHERE AUTHOR=?
3. //List<Book> findByauthor(String author);
4. List<Book> findByAuthor(String author);
5. List<Book> findByauthorIs(String author);
6. List<Book> findByAuthorEquals(String author);
7. //findBy -->SELECT + where = !=, > < null, not null, and or...
8. //SQL: select * from book where book_cost=?
9. List<Book> findByBookCostLessThanEqual(Double bookCost);
10.
11. //SQL: select * from book where book_id!=?
12. //List<Book> findByBookIdNot(Integer bookId);
13.
14. //SQL: select * from book where cost = ?
15. //List<Book> findByBookCostEqual(Double bookCost);
16.
17. //SQL: select * from book where cost >= ?
18. //List<Book> findByBookCostGreaterThan(Double bookCost);
19.
20. //SQL: select * from book where author is null
21. List<Book> findByAuthorIsNull();
22.
23. //SQL: select * from book where author is not null
24. //List<Book> findByAuthorIsNotNull();
25. //List<Book> findByAuthorNotNull();
26.
27. //------------Like Operator---------------------
Chapter-02
Spring Boot Data JPA
28. //SQL: Select * from book where author like ?
29. List<Book> findByAuthorLike(String expression);
30.
31. //SQL: Select * from book where author like ? order by bookname DESC
32. List<Book> findByAuthorLikeOrderByBookNameDesc(String expression);
33.
34. //SQL: Select * from book where author not like ?
35. //List<Book> findByAuthorNotLike(String expression);
36.
37. //SQL: Select * from book where author like 'input%'
38. List<Book> findByAuthorStartingWith(String input);
39.
40.
41. //SQL: Select * from book where author like '%input'
42. List<Book> findByAuthorEndingWith(String input);
43.
44. //SQL: Select * from book where author like '%input%'
45. List<Book> findByAuthorContaining(String input);
46.
47. //SQL: Select * from book where bid between x and y
48. List<Book> findByBookIdBetween(Integer id1,Integer id2);
49.
50. //--------------AND / OR --------------------------
51. //SQL: select * from book where bookId <= ? or bookType like ?
52. List<Book> findByBookIdLessThanEqualOrBookTypeLike(Integer bookId, String input);
53. }

Getting single Record:

1. Optional<Book> findByBookIdIs(Integer id);

****Getting Multiple records using Projection Operations


- To fetching specific properties/columns value, we need to provide Type interface
with certain properties related getter methods declaration and by using this
interface spring data jpa generating one model/entity class as In Memory proxy
class.
- If we want to generate in-memory proxy model/entity as class properties mid,
mname then we need to define interface as below-

1. interface ResultView{
2. public Integer getMid();
3. public String getMname();
4. }

We cannot add Lombok api @Getter annotation we need getter() method declaration only but not
definition.

So, finder method return type like List<ResultView> or Iterable<ResultView>

Example:
Chapter-02
Spring Boot Data JPA
Step #1: Define one Type Interface having getter methods for excepted properites

1. interface ResultView{
2. public Integer getMid();
3. public String getMname();
4. }

Step #2: Take finder method in Repository(I) that method return type List<ResultView> or
Iterable<ResultView>
1. public interface IMovieRepository extends JpaRepository<Movie, Integer> {
2. public List<ResultView> findByMidGreaterThanEqualAndMidLessThanEqual(int startId, int endId)
3.}

Step #3: In service class

1. Public class MovieService{


2. Public void fetchingProjectionRecords(){
3. List<ResultView> view
4. =repo.findByMidGreaterThanEqualAndMidLessThanEqual(100,500);
5. View.forEach(v->{
6. System.out.print(v.getMid + “ ” + v.getMName)
7. })
8. }
9. }

Limitations of finder method


1. Only select operations are possible
2. Aggregate operations are no possible
3. Group By clause operation not possible
4. Working with projection is more difficult
5. We can no use PL/SQL and functions
6. Sub-query is not possible
7. We cannot use join operations … etc.
Chapter-02
Spring Boot Data JPA
Chapter-02
Spring Boot Data JPA
=======
@Query
=======
- @Query method means, the @Query annotation that is added on top of the
method declared in the repository.
- @Query methods support only SELECT operations.
- @Query + @Modifying support select and non-select operations.

Syntax:
@Query(“HQL/JPQL query (or) Native SQL query”)
<returnType> anyMethodName(paramName)

Where,
- HQL/JPQL Query: Queries are developed using entity class name and properties
names. So, Queries are DB s/w independent.
 The underlying ORM s/w converts every HQL/JPQL queries into DB specific
SQL query internally by support Dialect component.

- Native SQL Query: queries are developed using DB table names and table column
names. So, queries are DB s/w dependent.

Advantages of @Query method:


1. Support both SELECT or Non-select operations
2. Taking any name for method
3. Can work with SQL or HQL/JPQL queries
4. Support JOINs aggregate function, sub-queries and more…
Q) Why we cannot use @Query method for INSERT operation as HQL/JPQL or SQL
query?
Answer:
- HQL/JPQL or SQL INSERT queries do not work with generators to generated ID
value. But in ORM in Spring Data JPA, Id property must have the generator to
generated id value. So we use save(-) or saveAll(-) for insert operations that works
with the generators to generated id value.
Chapter-02
Spring Boot Data JPA
----------------------------
HQL and JPQL Query
----------------------------
- These are database independent query
- These queries will be written by using Entity class name and its properties.
- Allows both ordinal parameter (?1 ?2) and named parameter (:<name>)
- Support aggregate function, joins, sub-queries, conditional clauses.
- HQL/JPQL queries are partial case sensitive means java identifiers like entity class
name and its property names are case sensitive and SQL words case-insensitive --
SELECT, WHERE, FROM... etc.

Disadvantages:
- HQL/JPQL based insert operation is not possible.
- HQL/JPQL based DDL (create table, alter table, drop table… etc.) operation is not
possible.
- HQL/JPQL based PL/SQL procedure and function are not possible.

HQL/JPQL SELECT queries:


- If HQL/JPQL query retrieving all columns value from DB table then writing SELECT
keyword is optional.
- Example:
SQL >> select * from employee
HQL >> from Employee;

- If HQL/JPQL query retrieving specific columns from DB table then writing SELECT
keyword is mandatory.
- Example:
SQL >> select emp_name, emp_salary from employee
HQL >> select empName, empSalary from Employee;

HQL/JPQL query with WHERE clause using parameter (positional param, name param):

Parameters: - Input given to Query at runtime.


1. Ordinal Parameters (?1, ?2 … etc.)
 This is given by JPA and used to indicate inputs to Query in order.
2. Named Parameters (:abc, :empId, :myIds, :names … etc.)
 It is a better way of passing or identify parameters (based on names)
Chapter-02
Spring Boot Data JPA
Examples:
SQL >> SELECT * FROM employee WHERE emp_id >=? AND emp_id <=?
JPQL Positional Param >> FROM Employee WHERE empId>=?1 AND empId<=?2
JPQL Named Param >> FROM Employee WHERE empId>=:Id AND empId<=:Id1

SQL >> SELECT * FROM employee WHERE emp_name IN (?,?,?)


JPQL PP >> FROM Employee WHERE empName IN (?1, ?2, ?3)
JPQL NParam >> FROM Employee WHERE empName IN (:emp1, :emp2, :emp3)

SQL >> UPDATE employee SET emp_name=? WHERE emp_id =?


JPQL PP >> UPDATE employee SET empName=?1 WHERE empId =?2
JPQL NParam >> UPDATE employee SET empName=:name WHERE empId =:id

Coding
1. Public interface IBookRepository extends JpaRepository<Book, Integer>{
2. //SQL: select * from booktab where author=?
3. //@Query("SELECT b FROM Book b WHERE b.author=?1")
4. @Query("SELECT b FROM Book b WHERE b.author = :authorName")
5. List<Book> getBooksByAuthor(String authorName);
6.
7. //SQL: select * from booktab where author like ? or bcost > ?
8. //@Query("SELECT * FROM Book WHERE bookCost > :bookCost OR author like :author")
9. @Query("SELECT * FROM Book WHERE author like ?1 OR bookCost >?2 OR bookType=?3")
10. List<Book> getBooksAuthorCost(String author, Double bookCost, String bType);
11. }

Note: if the query param name do not matching with method param name then use
@Param annotation. Working with named param by matching their names with method
param names is good practice.
Example:
@Query("SELECT b FROM Book b WHERE b.author = :abc")
List<Book> getBooksByAuthor(@Param("abc") String author);

Note: No. of parameters present in Query and no. of parameters present in method
param must be same (same count).
Chapter-02
Spring Boot Data JPA
HQL/JPQL query (selecting all columns value from DB table). Return type List of entity object.
1. public IMovieRepository extends JpaRepository{
2. @Query(“from Movie where mname in(:name1, :name2, : name3)”)
3. List<Movie> searchMovieByName(String name1, String name2, String name3);
4. }

HQL/JPQL query (selecting specific multiple columns value from DB table). Return type List of
object class obj[].
1. public interface IMovieRepository extends JpaRepository<Movie, Integer>{
2. @Query(“select mid, mname, year from Movie where rating >=:rat and year in(:y1, :y2)”)
3. List<Object[]> fetchMovieByRatingAndYear(float rat, String y1, String y2);
4. }

HQL/JPQL query (selecting single column value from DB table). Return type List of
<propertyType>.
1. public IMovieRepository extends JpaRepository<Movie, Integer>{
2. @Query(“select mname from Movie where year in(:y1, :y2, :y3) order by mname desc”)
3. List<String> fetchingMovieByYears(String y1, String y2, String y3);
4. }

Q) When we have readymade method findById(), then why should we use @Query methods
for single row Operations?
Answer:
- The findByAll(-) method can take only pk id value but @Query method for single
row operation we can take other unique column value.
Example: Getting specific single column value of single row/record
1. @Query(“select releaseDate from Movie where mname = :name”)
2. public String fetchingMovieReleaseDateByName(String name)
3.
4. //service class
5. Stirng releaseDate = repo. fetchingMovieReleaseDateByName(“RRR”)

Aggregate function with @Query method


1. @Query(“select max(rating), sum(year), min(rating) from Movie”)
2. public Object fetchingAggregateData();
3.
4. //service class
5. Object result[] = (Object[]) repo.fetchingAggregateData();

Sub-Query with @Query method


1. @Query(“from Movie where rating = (select max(rating) from Movie)”)
2. public List<Movie> fetchMaxRatingMovies();
Chapter-02
Spring Boot Data JPA
======================
Transaction Management
======================
- Whenever any client (CLI/GUI/App) sends query (UPDATE/DELETE/INSERT) then
that will be executed at buffer memory.
- If commit is called then it will update in Database, else if rollback is called then it
will cancel those changes.

- @Transactional: In Spring framework this annotation checks that all queries/one


query is executed successfully or not? If they are success then commit, else
rollback.
 We need to apply this annotation manually, over methods. Here, it is
recommended to apply for NON-SELECT operations.
- In Spring Boot, Spring Data jpa provides auto transactional for all pre-define
methods.
- In Spring Boot if we want to custom non-select HQL/JPQL query then we need to
add @Transactional annotation manually on top of the methods of Interface.

=============================================
Performing Non- select Operation using HQL/JPQL
=============================================
- For non-selecting we need to take @Modifying + @Query(__) methods in our Repository
interface. @Modifying indicates that Query is either UPDATE or DELETE

- If we execute non-select query (Delete, Update) then we need to add @Transactional


annotation that having ability to commit or rollback the DB operation.

- If we are taking separate Service layer by using @Service annotation then, placing
@Transactional annotation on top of the Repository interface or interface methods are
optional. Because @Service annotation will take care of Transaction management.

- If we are not taking separate Service layer then we must place @Transaction on top of
the Repository Interface or interface @Query(_) method + @Modifying

- Generally, @Query(_) + @Modifying methods return type int or byte or sort or long
because of non-select HQL/JPQL query return no. of records that are effected in numeric
format.
Chapter-02
Spring Boot Data JPA
Example:
1. @Transactional
2. public IEmployeeRepository extends JpaRepository<Employee, Integer> {
3. @Modifying
4. //@Transactional
5. @Query(“update Employee set address=:address where empId=:id”)
6. public int modifyEmpAddress(String address, Integer id)
7.
8. @Modifying
9. //@Transactional
10. @Query(“delete from Employee where empId=:id”)
11. public int modifyEmpAddress(Integer id)
12. }

Note: Instead of placing @Transactional on top of the every @Query(_) + @Modifying


methods it is recommended to place only once on top of the Repository interface.

=============================
Working with Native SQL Query
=============================
- If certain operations are not possible using readymade methods or finder
methods or @Query(_) methods then prefer to use Native SQL query.
- For that we need to place “nativeQuery=true” in @Query(_) methods and also
we need to add @Modifying and @Transactional annotation.
- Spring data jpa native query support positional param (?, ?, ?), ordinal param (?
1, ?2, ?3) and named param (:name, :id).
- Native query will be written using db table name and columns name that is native
query is db dependent.

- We generally use native query for below operations


 To execute insert SQL query
 DB s/w specific aggregate operation
 DB s/w specific date time function like SysDate for oracle and now() for
MySQL.
 To execute DDL queries
 To work with JDBC style positional param (?, ?, ?)
Chapter-02
Spring Boot Data JPA
Example:

1. @Transactional
2. public IEmployeeRepository extends JpaRepository<Employee, Integer> {
3. @Modifying
4. @Query(value=“insert into emp_reg values(mid_seq.NEXTVAL,?,?)”, nativeQuery=true)
5. public int registerEmployee(String empName, double salary);
6.
7. @Modifying
8. @Query(value= “select SysDate from dual”, nativeQuery=true)
9. public String fetchingSystemDate();
10. }

Note: create MID_SEQ.NEXTVAL sequence in DB s/w.

==============================
Working with Collection Mapping
==============================
- For form input types like [text field, radio, password, single select drop down,
text area] create a variable with primitive type like String, Integer, Double, Long,
Float … etc.
- For Form input types like [multi-select dropdown, checkbox for select multiple
options] create variable as collection types (List, Set, Map …etc.)
- In Database concept all primitives are stored as one primary table (Parent table)
and for every collection (List, Set, Map) create separate child tables.
- In ORM
 All primitive variables = 1 table
 1 primitive variable = 1 column
 1 collection variable = 1 child table with 2/3 columns
- We have 2 Types of collections mapping: -
 Index Based Collection: (child table - 3 columns) List (Index 0,1,2,3) and
Map (Map Key behaves as index). Because List can contain duplicate value
that’s why index.
 Non-Index based Collection: (child table - 2 columns) Set [No index
column here because value is unique]
 3 columns:
 Key Column (FK Column / Join Column) that is Pk from Parent Table.
 Index Column (Optional to config)
 Element Column (Data Column)
Chapter-02
Spring Boot Data JPA
Annotations of collection mapping:
1. @ElementCollection [mandatory]
 We must apply @ElementCollection annotation on top of every collection
variable. This annotation creates child table for every collection variable with 2/3
columns
2. @CollectionTable [Optional]
 To specify child table name
3. @JoinColumn [Optional]
 To specify FK column name of child table that is linked with PK column of Parent
table.
Syntax:
@CollectionTable(name= “childTableName”,
joinColumns= @JoinColumn(
name=“FK_col_name”,referencedColumnName= “PkColName”))
4. @OrderColumn (name= “indexColNameForList”) [Optional]
5. @Column (name= “DataColName”) [Optional]
6. @MapKeyColumn (name = “indexColNameForMap”) [Optional]
7. @ListIndexBase(value=1): It specify the start/base value of list index

1. @Entity
2. public class EmployeeInfo {
3. @Id
4. private Integer eid;
5. private String ename;
6.
7. @ElementCollection
8. @CollectionTable(name="emp_info_friends",
9. joinColumns = @JoinColumn(name="eidFk")
10. )
11. @OrderColumn(name="frnd_indx") //index
12. @Column(name="friends_list")
13. private List<String> friends;
14.
15. @ElementCollection
16. @CollectionTable(name="emp_info_phn_num",
17. joinColumns = @JoinColumn(name="eidFk")
18. )
19. @Column(name="phn_num")
20. private Set<String> phnNumber;
21.
22. @ElementCollection //must
23. @CollectionTable(name="emp_info_idcart_dtls",//table name
24. joinColumns = @JoinColumn(name="eidfk")//Fk column
25. )
26. @MapKeyColumn(name="idcart_indx") //index
27. @Column(name="idcart_dtls") //element column
28. private Map<Integer, String> idCartDtls;
29. }
Chapter-02
Spring Boot Data JPA

Providing Collection table name and Columns name are good practice. Using below
naming rules-
1. Child Table name = “parentTableName_ListVariableName”
2. Join column name = “ListVaribaleName_PKColumnName”
3. Data column name = “CollectionVartibaleName”

==================================
Association/HAS-A Relation Mapping
==================================

- Need of Association Mapping


 Storing multiple entities/table data into single db table is going to
following below problems-
 Data redundancy problem (Data duplication Problem)
 Maintenance problem

Example:
emp_id emp_name emp_gender address phone_number number_type
01 AA M xxyy 09800098 personal
01 AA M ZZHh 0293480 home
02 BB F pkiu 0213944 personal
03 CC M rtu 7645333 personal
Personal details in single table Data redundancy problem

To solve this problem, we need to keep two separate table/entities and connect two
tables of entities using PK in parent table and FK in child table.
Chapter-02
Spring Boot Data JPA
The possible association between db tables are
1. One to one
2. One to Many
3. Many to One
4. Many to Many
In java to build association between parent and child entity classes using HAS-A relation.
We can take two types of HAS-A relation for this association mapping in Entity classes.

1. Collection Type HAS-A relation


 1 to Many
 Many to Many
2. Non-collection Type HAS-A Relation
 1 to 1
 Many to One

The Association mapping Hibernate Annotations are


 @OneToOne
 @OneToMany
 @ManyToOne
 @ManyToMany
 @JoinColumn: used to provide FK column name
 @JoinTable: used to provide child table name

======================Coding Steps====================================
Step#1: Define two entity classes
Step#2: Apply HAS-A Relation (Created child class variable in Parent class)
Step#3: Check for Collection/Non-Collection type
Step#4: Apply Mapping Annotation and Fk Columns
Step#5: Just draw two tables with sample columns.

Note:
- Do not add @Data Lombok annotation on top of the entity classes in association
mapping because it gives overriding methods like hashCode(), toString(),
equels() ..etc. they may gives problem when storing object in Collections.
- Instead of @Data annotation we can add @Getter, @Setter, @NoArgConstructor,
@AllArgConstructor annotation on top of the Entity classes.
Chapter-02
Spring Boot Data JPA
==========
FetchType
==========
- To fetch data from multiple entities(tables) as EAGER or LAZY format.
- FetchType it is a ENUM provided by JPA with two values: LAZY, EAGER

EAGER
- Fetch Parent class/table records with its connected child class/table records
simultaneously.
- Default eager for 1 to 1 and Many to 1 relationship
LAZY
- Fetch Only Parent class/table data when find__ method is called Do not fetch
child data until it is called externally.
- Default Lazy for 1...* and *...* default type is LAZY.

Example:
@OneToMany(fetch = FetchType.EAGER)
@ManyToOne(fetch = FetchType.LAZY)

=========
Cascading
========
- Apply on non-select operation (delete, update, insert)
-

Association (Has-A) Two types


 Composition
 If I remove parent table records along with child table record will be
removed. there is no chance of existing child table record without
parent table record.
Example: Student table and Marksheets table relation. Without
student there is no meaning of marksheet.
 Cascading: It is used to make a Strong relation between Entities.
Performing Operation on Parent Entity, same operation will be
applied to connected child entities.
 i.e. if we save/persist parent object then by default all its
connected child objects are also saved. (same applied for
delete/update...).
Chapter-02
Spring Boot Data JPA

 Aggregation
 Sometime child table record exists without parent class record that
is called loose coupling.
Example: Student table and Department table relation. When I
removed student table record along with if I removed department
table record then other student is affected.

 By Default, there is No Cascading applied. i.e. Aggregation is default;


we have to perform save/update/delete (ALL) operation on both
parent and child objects individually.

Example: @OneToMany(cascade = CascadeType.ALL)


@ManyToMany(cascade = CascadeType.ALL)

Note:
- 1 to many / 1 to 1 Use Cascade type like ALL/PERSIST/DELETE. Because One
parent might have been connected to multiple child’s.

- Many to 1 / Many to Many relations do not use DELETE cascading (we can use
PERSIST/MERGE). Because one child might have been connected to multiple
parent)

==========================
Working with Date and Time
==========================
- To inserting, retrieving DOB, TOB, DOJ, TOJ, record created time, last updated
date time, we need to date, time value.
 DOB :: Date of Birth
 TOB :: Time of Birth
 DOJ :: Date of Joining
 TOJ :: Time of Joining
- From java 1.8v new Date and Time API is given
 LocalDate: To get/set Date value
 LocalTime: to get/set Time value
 LocalDateTime: to get/set Date and Time value
Chapter-02
Spring Boot Data JPA
- In Oracle db s/w, the date and time related data types are
 Date (for date value only)
 Timestamp (for date and time values)
- In MySQL db s/w, the date and time related data types are
 Date, time and timestamp

- In entity class we need to define appropriate data type for date and time related
properties like LocalDate, LocalTime, LocalDateTime… etc.

Entity class with java 1.8v date and Time API Coding:

1. @Data
2. @Entity
3. public class PersonalInfo {
4. @Id
5. private Integer pid;
6. private String pname;
7. private LocalDate dob;
8. private LocalTime tob;
9. private LocalDateTime doj;
10. }

Date and Time Annotations:


 @Temporal: It is used to present data and time formats default is
DATEANDTIME(TIMESTAMP), we can even use DATE, TIME. Because in
java.util.Date package, there is no Date or Time specific class.
Example: @Temporal (TemporalType.DATE)

Note: only to create variable using java.util.Date package. No need for java
1.8v date and time API.
 @CreationTimeStamp: To generate record created date.
 @UpdateTimeStamp: To generate record updated date.

Example:
1. @Entity
2. public class Employee {
3.
4. @Id
5. private Integer empId;
6.
7. @Temporal(TemporalType.TIMESTAMP)//(default)
8. private Date dob;
Chapter-02
Spring Boot Data JPA
9.
10. @CreationTimestamp
11. @Column(name="date_created", updatable = false)
12. private LocalDate dateCreated;
13.
14. @UpdateTimestamp
15. @Column(name="last_updated", insertable = false)
16. private LocalDate lastUpdated;
17. }

=========================
Working with Large Objects
=========================
- Large object means files like image files, audio files, video files, text file, movie
files … etc.
- All major DB s/w support Large Objects
- In oracle gives BLOB, CLOB data types for large objects
- In MySQL gives TINYBLOB, BLOB, MEDIUMBLOB, LONGBLOB, Text, Medium Text,
Long Text.
- BLOB means binary files (images, audios, videos, graphics … etc.)
- CLOB means character files (text, csv files, rich text … etc.)
- We need to take byte [] for BLOB data type and char[] for CLOB data type in Entity
class.
- While developing standalone application we store LOBs file directly in db column.

- While developing web applications, distributed application, we generally avoiding


to store LOBs file into db table column. We store only file path as string and store
in db table column and files are store in server machine file system like s3, Bucket,
CDN (content delivery network), DMS (document management system) etc.

Annotations:
 @Lob
private byte [] image
 @Lob
private char[] resume
Chapter-02
Spring Boot Data JPA
==============================
Generate Custom Composite Key
==============================

- To work with Composite PKs we will use below 2 annotations


 @Embeddable: Class level annotation to represent primary key columns
 @EmbeddedId: Variable level annotation to present Embdedable class

Note: Generators will not support for Composite Primary keys.


Note: The class which is representing Composite Keys should implement Serializable interface.

Example:

Class which is represent Composite key


1. @Data
2. @Embeddable
3. public class AccountPK implements Serializable{
4. private Long accNum;
5. private String accType;
6. }

Entity class
1. @Data
2. @Entity
3. @Table(name="account_tbl")
4. public class Account {
5. private String holderName;
6. private String branch;
7.
8. @EmbeddedId
9. private AccountPK accountPk;
10. }

Repository
1. public interface AccountRepo
2. extends JpaRepository<Account, AccountPK>{
3. }
Chapter-02
Spring Boot Data JPA
==========
Generator
==========
- Ids is PK that is given from application after taking end-user data.
- Generators are two types
 Pre-defined Generators
 Custom Generators

Pre-defined Generator:
- @GeneratedValue annotation is used with GenerationType.
- GenerationType is ENUM has values are
 SEQUENCE
 It is mostly used for Oracle databases Object that generate numbers
 IDENTITY
 It is used for MySQL. (Auto-Increment).
 TABLE
 A table is created (behaves like sequence) and store id value.
 AUTO
 Any one option is selected based on DB

------------------------------
Coding: At Entity class
------------------------------
1. @Data
2. @Entity
3. public class Product {
4.
5. @Id
6. @GeneratedValue(strategy = GenerationType.AUTO)// SEQUENCE or IDENTITY
7. @Column(name="pid")
8. private String prodId;
9.
10. @Column(name="pname")
11. private String prodName;
12.
13. @Column(name="pcost")
14. private Double prodCost;
15.
16. }
Chapter-02
Spring Boot Data JPA
(or)
-------------------------------
Coding: At Entity Class
-------------------------------
1. @Data
2. @Entity
3. public class Product {
4.
5. @Id
6. @SequenceGenerator(name= “test” initialValue=1000,
7. allocationSize=1, sequenceName= “pid_seq”)
8. @GeneratedValue(generator= “test”, strategy = GenerationType.SEQUENCE)
9. @Column(name="pid")
10. private String prodId;
11.
12. @Column(name="pname")
13. private String prodName;
14.
15. @Column(name="pcost")
16. private Double prodCost;
17.
18. }

Where,
Generator = “test” is used to link
initialValue = starting from 1000 or our Requirement
allocationSize = increment
sequenceName = db Sequence Object name

--------------------------
Custom Generator:
--------------------------
- We want to generate primary key columns values as per our project requirement
like below-
Example:
OD_1
OD_2
OD_3
……
OD_nth

- To achieve this type of requirement, we need to develop our own generator. That
is called as Custom Generator.
Chapter-02
Spring Boot Data JPA
----------
Coding
----------

Step#1: Define one public class


Step#2: Implement IdentifierGenerator (org.hibernate.id)
Step#3: Override method generate()
Step#4: Define your own logic
Step#5: At Entity class
@GeneratedValue(generator = "<forLinkedAnyName>")
@GenericGenerator(
name="< forLinkedAnyName >", strategy="fullyQualifiedGeneratorClassName")

======================= CustomGenerator Class ========================

1. public class OrderIdGenerator implements IdentifierGenerator{


2. String prefix="OD_YM";
3. String suffix = "";
4. String sql = "select order_id.nextval from dual";
5. @Override
6. public Object generate(SharedSessionContractImplementor session,
7.
Object object) {
8. JdbcConnectionAccess jdbcConnectionAccess =
9. session.getJdbcConnectionAccess();
10.
11. try {
12. Connection con = jdbcConnectionAccess.obtainConnection();
13. Statement st = con.createStatement();
14. ResultSet rs = st.executeQuery(sql);
15. if(rs.next()) {
16. int nextval = rs.getInt(1);
17. suffix = String.valueOf(nextval);
18. }
19. } catch (SQLException e) {
20. e.printStackTrace();
21. }
22. return prefix+suffix;
23. }
24. }
25.

============================= Entity class ============================

1. @Entity
2. @Data
3. public class OrderDetails {
4. @Id
5. @GeneratedValue(generator="order_id")
6. @GenericGenerator(name="order_id",strategy="org.nadim.generator.OrderIdGenerator")
7. private String orderId;
8. }
Chapter-02
Spring Boot Data JPA
Q) How to insert partial data to records or how to perform partial save object
operation?
Example:
1. class student{
2. int sid;
3. String sname;
4. String gender;
5. String dept;
6. String email;
7. }
In this class we want to save student object with Student class properties sid, sname and
dept only. How?

Answer:
- Using save(-) or saveAll(-) methods. But keeping partial data to the given entity
object by making the remaining properties values as NULL or using @Transient
annotation on top of the entity class properties which are we do not want to
save.
Example: using null
Student std = new Student();
std.setSname(“nadim”);
std.setDept(“CES”);
//std.setGender(null); // place null value explicitly is optional
//std.setEmail(null);
repo.save(std);

Hibernate query: insert into student(sname, gender, dept, email) values (? ? ? ?)


To make Spring data JPA to generate INSERT query dynamically only based on non-null
values/properties then we need to add @DynamicInsert(true) annotation on top of the
entity class.
Hibernate query: insert into student(sname, dept) values (? ?)

Note: using @Transient annotation makes property as a non-persistence able property


that is not recommended.
Chapter-02
Spring Boot Data JPA
Q) Why there is only @DynamicInsert and @DynamicUpadate annotation, why we do
not have @DynamicDelete annotation?
Answer:
- DELETE SQL query delete the complete record by taking the criteria value. i.e.
there is not possibility to deleting partial values of the record using delete SQL
query. So, there is no @DynamicDelete.

Q) What is DAO?
Answer: DAO (Data Access Object) is a class that contains code to perform Database
Operations.

You might also like