原帖 https://grokonez.com/hibernate/use-hibernate-lazy-fetch-eager-fetch-type-spring-boot-mysql
In the tutorial, JavaSampleApproach will help you understand Hibernate Lazy Fetch Type and Eager Fetch Type by sample code with Spring Boot & MySql database.
I. Technologies
– Java 1.8 – Maven 3.3.9 – Spring Tool Suite – Version 3.8.1.RELEASE – Spring Boot: 1.5.1.RELEASE – MySql database
II. Hibernate Lazy Fetch & Eager Fetch Type
How to load all entities of relationships in RDBMS Database? -> Hibernate provides 2 strategies to retrieve entities(records) of all relationships: Lazy Fetch & Eager Fetch. So Hibernate Fetch Types are always associated with relationship annotations: @OneToOne, @OneToMany, @ManyToOne, @ManyToMany.
1. Eager Fetch Type
Hibernate Eager Fetch Type comes with setting: fetch = FetchType.EAGER
. Details:
@Table(name="company")
public class Company{
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private int id;
private String name;
@OneToMany(mappedBy = "company", cascade = CascadeType.ALL, fetch = FetchType.EAGER)
private Set<Product> products;
public Company(){
}
...
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
@Entity
@Table(name="company")
public class Company{
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private int id;
private String name;
@OneToMany(mappedBy = "company", cascade = CascadeType.ALL, fetch = FetchType.EAGER)
private Set<Product> products;
public Company(){
}
...
}
|
Hibernate Eager Fetch Type will load all the relationship entities at the initial time.
– Example, when calling companyRepository.findAll()
, all the records of product tables will be loaded by Hibernate and stored in Set products
of a Company object.
Details: – CompanyServices.java:
public class CompanyServices {
...
public void showData(){
List<Company> companyLst = companyRepository.findAll();
companyLst.forEach(System.out::println);;
}
...
}
1
2
3
4
5
6
7
8
9
|
@Service
public class CompanyServices {
...
public void showData(){
List<Company> companyLst = companyRepository.findAll();
companyLst.forEach(System.out::println);;
}
...
}
|
– Logs:
Hibernate: select company0_.id as id1_0_, company0_.name as name2_0_ from company company0_
Hibernate: select products0_.company_id as company_3_1_0_, products0_.id as id1_1_0_, products0_.id as id1_1_1_, products0_.company_id as company_3_1_1_, products0_.name as name2_1_1_ from product products0_ where products0_.company_id=?
Hibernate: select products0_.company_id as company_3_1_0_, products0_.id as id1_1_0_, products0_.id as id1_1_1_, products0_.company_id as company_3_1_1_, products0_.name as name2_1_1_ from product products0_ where products0_.company_id=?
=====================Show All Companies on console:====================
{"name":"Apple","products":[{"name":"Iphone 7"},{"name":"IPadPro"}]}
{"name":"Samsung","products":[{"name":"GalaxyJ7"},{"name":"GalaxyTabA"}]}
1
2
3
4
5
6
7
|
=====================Retrieve Companies from Database:====================
Hibernate: select company0_.id as id1_0_, company0_.name as name2_0_ from company company0_
Hibernate: select products0_.company_id as company_3_1_0_, products0_.id as id1_1_0_, products0_.id as id1_1_1_, products0_.company_id as company_3_1_1_, products0_.name as name2_1_1_ from product products0_ where products0_.company_id=?
Hibernate: select products0_.company_id as company_3_1_0_, products0_.id as id1_1_0_, products0_.id as id1_1_1_, products0_.company_id as company_3_1_1_, products0_.name as name2_1_1_ from product products0_ where products0_.company_id=?
=====================Show All Companies on console:====================
{"name":"Apple","products":[{"name":"Iphone 7"},{"name":"IPadPro"}]}
{"name":"Samsung","products":[{"name":"GalaxyJ7"},{"name":"GalaxyTabA"}]}
|
From the logs, having three select statements when calling function: companyRepository.findAll()
to load company entities and all relationship entities: products at initial time. Then for next processing step(showing them on console), all info of product entities are ready in memory for getting.
*** Note: should consider about memory & performance issues when working with Eager fetching strategy.
2. Lazy Fetch Type
Hibernate Lazy Fetch Type comes with setting: fetch = FetchType.LAZY
.
Details:
@Table(name="company")
public class Company{
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private int id;
private String name;
@OneToMany(mappedBy = "company", cascade = CascadeType.ALL, fetch = FetchType.LAZY)
private Set<Product> products;
public Company(){
}
public String toString(){
String info = "";
JSONObject jsonInfo = new JSONObject();
jsonInfo.put("name",this.name);
JSONArray productArray = new JSONArray();
if(this.products != null){
this.products.forEach(product->{
JSONObject subJson = new JSONObject();
subJson.put("name", product.getName());
productArray.put(subJson);
});
}
jsonInfo.put("products", productArray);
info = jsonInfo.toString();
return info;
}
...
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
|
@Entity
@Table(name="company")
public class Company{
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private int id;
private String name;
@OneToMany(mappedBy = "company", cascade = CascadeType.ALL, fetch = FetchType.LAZY)
private Set<Product> products;
public Company(){
}
public String toString(){
String info = "";
JSONObject jsonInfo = new JSONObject();
jsonInfo.put("name",this.name);
JSONArray productArray = new JSONArray();
if(this.products != null){
this.products.forEach(product->{
JSONObject subJson = new JSONObject();
subJson.put("name", product.getName());
productArray.put(subJson);
});
}
jsonInfo.put("products", productArray);
info = jsonInfo.toString();
return info;
}
...
}
|
Hibernate Eager Fetch Type will NOT load any entities (records) of relationships at the initial time. Need @Transaction annotation for Lazy Fetch to associate relationship loaded entities with a Hibernate session. If NOT, an exception will be thrown:
at org.hibernate.proxy.AbstractLazyInitializer.initialize(AbstractLazyInitializer.java:148) ~[hibernate-core-5.0.12.Final.jar:5.0.12.Final]
at org.hibernate.proxy.AbstractLazyInitializer.getImplementation(AbstractLazyInitializer.java:266) ~[hibernate-core-5.0.12.Final.jar:5.0.12.Final]
at org.hibernate.proxy.pojo.javassist.JavassistLazyInitializer.invoke(JavassistLazyInitializer.java:73) ~[hibernate-core-5.0.12.Final.jar:5.0.12.Final]
at com.javasampleapproach.jpa.one2many.model.Company_$$_jvstdfb_0.getName(Company_$$_jvstdfb_0.java) ~[classes/:na]
1
2
3
4
5
|
Caused by: org.hibernate.LazyInitializationException: could not initialize proxy - no Session
at org.hibernate.proxy.AbstractLazyInitializer.initialize(AbstractLazyInitializer.java:148) ~[hibernate-core-5.0.12.Final.jar:5.0.12.Final]
at org.hibernate.proxy.AbstractLazyInitializer.getImplementation(AbstractLazyInitializer.java:266) ~[hibernate-core-5.0.12.Final.jar:5.0.12.Final]
at org.hibernate.proxy.pojo.javassist.JavassistLazyInitializer.invoke(JavassistLazyInitializer.java:73) ~[hibernate-core-5.0.12.Final.jar:5.0.12.Final]
at com.javasampleapproach.jpa.one2many.model.Company_$$_jvstdfb_0.getName(Company_$$_jvstdfb_0.java) ~[classes/:na]
|
Details company loading service: – CompanyServices.java
public class CompanyServices {
...
@Transactional
public void showData(){
List<Company> companyLst = companyRepository.findAll();
companyLst.forEach(System.out::println);;
}
...
}
1
2
3
4
5
6
7
8
9
10
|
@Service
public class CompanyServices {
...
@Transactional
public void showData(){
List<Company> companyLst = companyRepository.findAll();
companyLst.forEach(System.out::println);;
}
...
}
|
Logs when calling the function: companyRepository.findAll()
:
Hibernate: select company0_.id as id1_0_, company0_.name as name2_0_ from company company0_
=====================Show All Companies on console:====================
Hibernate: select products0_.company_id as company_3_1_0_, products0_.id as id1_1_0_, products0_.id as id1_1_1_, products0_.company_id as company_3_1_1_, products0_.name as name2_1_1_ from product products0_ where products0_.company_id=?
{"name":"Apple","products":[{"name":"IPadPro"},{"name":"Iphone 7"}]}
Hibernate: select products0_.company_id as company_3_1_0_, products0_.id as id1_1_0_, products0_.id as id1_1_1_, products0_.company_id as company_3_1_1_, products0_.name as name2_1_1_ from product products0_ where products0_.company_id=?
{"name":"Samsung","products":[{"name":"GalaxyTabA"},{"name":"GalaxyJ7"}]}
1
2
3
4
5
6
7
|
=====================Retrieve Companies from Database:====================
Hibernate: select company0_.id as id1_0_, company0_.name as name2_0_ from company company0_
=====================Show All Companies on console:====================
Hibernate: select products0_.company_id as company_3_1_0_, products0_.id as id1_1_0_, products0_.id as id1_1_1_, products0_.company_id as company_3_1_1_, products0_.name as name2_1_1_ from product products0_ where products0_.company_id=?
{"name":"Apple","products":[{"name":"IPadPro"},{"name":"Iphone 7"}]}
Hibernate: select products0_.company_id as company_3_1_0_, products0_.id as id1_1_0_, products0_.id as id1_1_1_, products0_.company_id as company_3_1_1_, products0_.name as name2_1_1_ from product products0_ where products0_.company_id=?
{"name":"Samsung","products":[{"name":"GalaxyTabA"},{"name":"GalaxyJ7"}]}
|
Difference with Eager Fetch, at retrieving Company entities step, just having one select statement to load company entities while invoking the function: companyRepository.findAll()
. When showing relationship entities(products) info, having 2 others select statements to load product records from database.
III. Practice
Step to do: – Create SpringBoot project – Create Models – Create JPA Repositories – Implement Services – Configure Datasource & Spring JPA – Implement a test Client – Run & Check results
1. Create SpringBoot project
– Using SpringToolSuite, create a SpringBoot project. Then add needed dependencies:
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.json</groupId>
<artifactId>json</artifactId>
</dependency>
1
2
3
4
5
6
7
8
9
10
11
12
13
|
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.json</groupId>
<artifactId>json</artifactId>
</dependency>
|
2. Create Models
2 Entities Company and Product that having One-to-Many relationship:
2.1 Company entity
import java.util.Set;
import javax.persistence.CascadeType;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.OneToMany;
import javax.persistence.Table;
import org.json.JSONArray;
import org.json.JSONObject;
@Entity
@Table(name="company")
public class Company {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private int id;
private String name;
@OneToMany(mappedBy = "company", cascade = CascadeType.ALL, fetch = FetchType.EAGER)
private Set<Product> products;
public Company(){
}
public Company(String name){
this.name = name;
}
public Company(String name, Set<Product> products){
this.name = name;
this.products = products;
}
// name
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
// products
public void setProducts(Set<Product> products){
this.products = products;
}
public Set<Product> getProducts(){
return this.products;
}
public String toString(){
String info = "";
JSONObject jsonInfo = new JSONObject();
jsonInfo.put("name",this.name);
JSONArray productArray = new JSONArray();
if(this.products != null){
this.products.forEach(product->{
JSONObject subJson = new JSONObject();
subJson.put("name", product.getName());
productArray.put(subJson);
});
}
jsonInfo.put("products", productArray);
info = jsonInfo.toString();
return info;
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
|
package com.javasampleapproach.hibernate.fetchtype.model;
import java.util.Set;
import javax.persistence.CascadeType;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.OneToMany;
import javax.persistence.Table;
import org.json.JSONArray;
import org.json.JSONObject;
@Entity
@Table(name="company")
public class Company {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private int id;
private String name;
@OneToMany(mappedBy = "company", cascade = CascadeType.ALL, fetch = FetchType.EAGER)
private Set<Product> products;
public Company(){
}
public Company(String name){
this.name = name;
}
public Company(String name, Set<Product> products){
this.name = name;
this.products = products;
}
// name
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
// products
public void setProducts(Set<Product> products){
this.products = products;
}
public Set<Product> getProducts(){
return this.products;
}
public String toString(){
String info = "";
JSONObject jsonInfo = new JSONObject();
jsonInfo.put("name",this.name);
JSONArray productArray = new JSONArray();
if(this.products != null){
this.products.forEach(product->{
JSONObject subJson = new JSONObject();
subJson.put("name", product.getName());
productArray.put(subJson);
});
}
jsonInfo.put("products", productArray);
info = jsonInfo.toString();
return info;
}
}
|
2.2 Product entity
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.Table;
import org.json.JSONObject;
@Entity
@Table(name="product")
public class Product {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private int id;
private String name;
@ManyToOne(fetch = FetchType.EAGER)
@JoinColumn(name = "company_id")
private Company company;
public Product(){
}
public Product(String name){
this.name = name;
}
public Product(String name, Company company){
this.name = name;
this.company = company;
}
// name
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
// products
public void setCompany(Company company){
this.company = company;
}
public Company getCompany(){
return this.company;
}
public String toString(){
String info = "";
JSONObject jsonInfo = new JSONObject();
jsonInfo.put("name",this.name);
JSONObject companyObj = new JSONObject();
companyObj.put("name", this.company.getName());
jsonInfo.put("company", companyObj);
info = jsonInfo.toString();
return info;
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
|
package com.javasampleapproach.hibernate.fetchtype.model;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.Table;
import org.json.JSONObject;
@Entity
@Table(name="product")
public class Product {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private int id;
private String name;
@ManyToOne(fetch = FetchType.EAGER)
@JoinColumn(name = "company_id")
private Company company;
public Product(){
}
public Product(String name){
this.name = name;
}
public Product(String name, Company company){
this.name = name;
this.company = company;
}
// name
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
// products
public void setCompany(Company company){
this.company = company;
}
public Company getCompany(){
return this.company;
}
public String toString(){
String info = "";
JSONObject jsonInfo = new JSONObject();
jsonInfo.put("name",this.name);
JSONObject companyObj = new JSONObject();
companyObj.put("name", this.company.getName());
jsonInfo.put("company", companyObj);
info = jsonInfo.toString();
return info;
}
}
|
@Entity: Specifies that the class is an entity. This annotation is applied to the entity class. @Id: Specifies the primary key of an entity. @OneToMany: Defines a many-valued association with one-to-many multiplicity. @ManyToOne: Defines a single-valued association to another entity class that has many-to-one multiplicity @JoinColumn: Specifies a column for joining an entity association or element collection. If the JoinColumn annotation itself is defaulted, a single join column is assumed and the default values apply.
3. Create JPA Repositories
Create 2 interface repositories by extends JpaRepository
: – CompanyRepository.java
import org.springframework.data.jpa.repository.JpaRepository;
import com.javasampleapproach.jpa.one2many.model.Company;
public interface CompanyRepository extends JpaRepository<Company, Integer>{
}
1
2
3
4
5
6
7
8
|
package com.javasampleapproach.hibernate.fetchtype.repository;
import org.springframework.data.jpa.repository.JpaRepository;
import com.javasampleapproach.jpa.one2many.model.Company;
public interface CompanyRepository extends JpaRepository<Company, Integer>{
}
|
– ProductRepository.java
import org.springframework.data.jpa.repository.JpaRepository;
import com.javasampleapproach.jpa.one2many.model.Product;
public interface ProductRepository extends JpaRepository<Product, Integer>{
}
1
2
3
4
5
6
7
8
|
package com.javasampleapproach.hibernate.fetchtype.repository;
import org.springframework.data.jpa.repository.JpaRepository;
import com.javasampleapproach.jpa.one2many.model.Product;
public interface ProductRepository extends JpaRepository<Product, Integer>{
}
|
4. Implement Services
– CompanyServices.java:
import java.util.List;
import javax.transaction.Transactional;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.javasampleapproach.jpa.one2many.model.Company;
import com.javasampleapproach.jpa.one2many.repository.CompanyRepository;
@Service
public class CompanyServices {
@Autowired
CompanyRepository companyRepository;
public void save(Company company){
companyRepository.save(company);
}
@Transactional
public void showData(){
System.out.println("=====================Retrieve Companies from Database:====================");
List<Company> companyLst = companyRepository.findAll();
System.out.println("=====================Show All Companies on console:====================");
companyLst.forEach(System.out::println);;
}
public void deleteAll(){
companyRepository.deleteAll();
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
|
package com.javasampleapproach.hibernate.fetchtype.services;
import java.util.List;
import javax.transaction.Transactional;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.javasampleapproach.jpa.one2many.model.Company;
import com.javasampleapproach.jpa.one2many.repository.CompanyRepository;
@Service
public class CompanyServices {
@Autowired
CompanyRepository companyRepository;
public void save(Company company){
companyRepository.save(company);
}
@Transactional
public void showData(){
System.out.println("=====================Retrieve Companies from Database:====================");
List<Company> companyLst = companyRepository.findAll();
System.out.println("=====================Show All Companies on console:====================");
companyLst.forEach(System.out::println);;
}
public void deleteAll(){
companyRepository.deleteAll();
}
}
|
– ProductServices.java:
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import com.javasampleapproach.jpa.one2many.model.Product;
import com.javasampleapproach.jpa.one2many.repository.ProductRepository;
@Service
public class ProductServices {
@Autowired
ProductRepository productRepository;
public void save(Product product){
productRepository.save(product);
}
@Transactional
public void showData(){
System.out.println("=====================Retrieve Products from Database:====================");
List<Product> productLst = productRepository.findAll();
System.out.println("=====================Show All Products on console:====================");
productLst.forEach(System.out::println);
}
public void deleteAll(){
productRepository.deleteAll();
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
|
package com.javasampleapproach.hibernate.fetchtype.services;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import com.javasampleapproach.jpa.one2many.model.Product;
import com.javasampleapproach.jpa.one2many.repository.ProductRepository;
@Service
public class ProductServices {
@Autowired
ProductRepository productRepository;
public void save(Product product){
productRepository.save(product);
}
@Transactional
public void showData(){
System.out.println("=====================Retrieve Products from Database:====================");
List<Product> productLst = productRepository.findAll();
System.out.println("=====================Show All Products on console:====================");
productLst.forEach(System.out::println);
}
public void deleteAll(){
productRepository.deleteAll();
}
}
|
About showData()
function, we must implement with @Transactional for Lazy Fetch Type. But @Transactional is optional with Eager FetchType.
5. Configure Datasource & Spring JPA
Open application.properties, configure spring.datasource & spring.jpa:
spring.datasource.username=root
spring.datasource.password=12345
spring.jpa.generate-ddl=true
spring.jpa.show-sql=true
spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.MySQL5Dialect
1
2
3
4
5
6
7
|
spring.datasource.url=jdbc:mysql://localhost:3306/testdb
spring.datasource.username=root
spring.datasource.password=12345
spring.jpa.generate-ddl=true
spring.jpa.show-sql=true
spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.MySQL5Dialect
|
6. Implement a test Client
Use 2 repository: CompanyRepository & ProductRepository
CompanyServices companyService;
@Autowired
ProductServices productService;
1
2
3
4
5
|
@Autowired
CompanyServices companyService;
@Autowired
ProductServices productService;
|
Implement 3 functions: – clearData()
is used to empty 2 tables company & product – saveData()
is used to persist entities (Company & Product) to database – showData()
is used to load all records (Company & Product) and show all on console.
Full SourceCode:
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.javasampleapproach.jpa.one2many.model.Company;
import com.javasampleapproach.jpa.one2many.model.Product;
import com.javasampleapproach.jpa.one2many.services.CompanyServices;
import com.javasampleapproach.jpa.one2many.services.ProductServices;
@SpringBootApplication
public class SpringJpaOneToManyRelationshipApplication implements CommandLineRunner{
@Autowired
CompanyServices companyService;
@Autowired
ProductServices productService;
public static void main(String[] args) {
SpringApplication.run(SpringJpaOneToManyRelationshipApplication.class, args);
}
@Override
public void run(String... arg0) throws Exception {
clearData();
saveData();
showData();
}
private void clearData(){
System.out.println("=================== Clear DATA =======================");
companyService.deleteAll();
productService.deleteAll();
}
private void saveData(){
System.out.println("=================== Save DATA =======================");
Product iphone7 = new Product("Iphone 7");
Product iPadPro = new Product("IPadPro");
Product galaxyJ7 = new Product("GalaxyJ7");
Product galaxyTabA = new Product("GalaxyTabA");
Company apple = new Company("Apple");
Company samsung = new Company("Samsung");
// set company for products
iphone7.setCompany(apple);
iPadPro.setCompany(apple);
galaxyJ7.setCompany(samsung);
galaxyTabA.setCompany(samsung);
// save companies
companyService.save(apple);
companyService.save(samsung);
// save products
productService.save(iphone7);
productService.save(iPadPro);
productService.save(galaxyJ7);
productService.save(galaxyTabA);
}
private void showData(){
System.out.println("=================== Show ALL Data =======================");
companyService.showData();
productService.showData();
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
|
package com.javasampleapproach.hibernate.fetchtype;
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.javasampleapproach.jpa.one2many.model.Company;
import com.javasampleapproach.jpa.one2many.model.Product;
import com.javasampleapproach.jpa.one2many.services.CompanyServices;
import com.javasampleapproach.jpa.one2many.services.ProductServices;
@SpringBootApplication
public class SpringJpaOneToManyRelationshipApplication implements CommandLineRunner{
@Autowired
CompanyServices companyService;
@Autowired
ProductServices productService;
public static void main(String[] args) {
SpringApplication.run(SpringJpaOneToManyRelationshipApplication.class, args);
}
@Override
public void run(String... arg0) throws Exception {
clearData();
saveData();
showData();
}
private void clearData(){
System.out.println("=================== Clear DATA =======================");
companyService.deleteAll();
productService.deleteAll();
}
private void saveData(){
System.out.println("=================== Save DATA =======================");
Product iphone7 = new Product("Iphone 7");
Product iPadPro = new Product("IPadPro");
Product galaxyJ7 = new Product("GalaxyJ7");
Product galaxyTabA = new Product("GalaxyTabA");
Company apple = new Company("Apple");
Company samsung = new Company("Samsung");
// set company for products
iphone7.setCompany(apple);
iPadPro.setCompany(apple);
galaxyJ7.setCompany(samsung);
galaxyTabA.setCompany(samsung);
// save companies
companyService.save(apple);
companyService.save(samsung);
// save products
productService.save(iphone7);
productService.save(iPadPro);
productService.save(galaxyJ7);
productService.save(galaxyTabA);
}
private void showData(){
System.out.println("=================== Show ALL Data =======================");
companyService.showData();
productService.showData();
}
}
|
7. Run & Check results
7.1 Run with Eager Fetch Type
Build & Run the project with SpringBoot App mode. The sourcecode is ready with Eager Fetch Type config for both Company & Product. – Logs:
Hibernate: select company0_.id as id1_0_, company0_.name as name2_0_ from company company0_
Hibernate: select products0_.company_id as company_3_1_0_, products0_.id as id1_1_0_, products0_.id as id1_1_1_, products0_.company_id as company_3_1_1_, products0_.name as name2_1_1_ from product products0_ where products0_.company_id=?
Hibernate: select products0_.company_id as company_3_1_0_, products0_.id as id1_1_0_, products0_.id as id1_1_1_, products0_.company_id as company_3_1_1_, products0_.name as name2_1_1_ from product products0_ where products0_.company_id=?
=====================Show All Companies on console:====================
{"name":"Apple","products":[{"name":"Iphone 7"},{"name":"IPadPro"}]}
{"name":"Samsung","products":[{"name":"GalaxyJ7"},{"name":"GalaxyTabA"}]}
=====================Retrieve Products from Database:====================
Hibernate: select product0_.id as id1_1_, product0_.company_id as company_3_1_, product0_.name as name2_1_ from product product0_
Hibernate: select company0_.id as id1_0_0_, company0_.name as name2_0_0_, products1_.company_id as company_3_1_1_, products1_.id as id1_1_1_, products1_.id as id1_1_2_, products1_.company_id as company_3_1_2_, products1_.name as name2_1_2_ from company company0_ left outer join product products1_ on company0_.id=products1_.company_id where company0_.id=?
Hibernate: select company0_.id as id1_0_0_, company0_.name as name2_0_0_, products1_.company_id as company_3_1_1_, products1_.id as id1_1_1_, products1_.id as id1_1_2_, products1_.company_id as company_3_1_2_, products1_.name as name2_1_2_ from company company0_ left outer join product products1_ on company0_.id=products1_.company_id where company0_.id=?
=====================Show All Products on console:====================
{"name":"Iphone 7","company":{"name":"Apple"}}
{"name":"IPadPro","company":{"name":"Apple"}}
{"name":"GalaxyJ7","company":{"name":"Samsung"}}
{"name":"GalaxyTabA","company":{"name":"Samsung"}}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|
=====================Retrieve Companies from Database:====================
Hibernate: select company0_.id as id1_0_, company0_.name as name2_0_ from company company0_
Hibernate: select products0_.company_id as company_3_1_0_, products0_.id as id1_1_0_, products0_.id as id1_1_1_, products0_.company_id as company_3_1_1_, products0_.name as name2_1_1_ from product products0_ where products0_.company_id=?
Hibernate: select products0_.company_id as company_3_1_0_, products0_.id as id1_1_0_, products0_.id as id1_1_1_, products0_.company_id as company_3_1_1_, products0_.name as name2_1_1_ from product products0_ where products0_.company_id=?
=====================Show All Companies on console:====================
{"name":"Apple","products":[{"name":"Iphone 7"},{"name":"IPadPro"}]}
{"name":"Samsung","products":[{"name":"GalaxyJ7"},{"name":"GalaxyTabA"}]}
=====================Retrieve Products from Database:====================
Hibernate: select product0_.id as id1_1_, product0_.company_id as company_3_1_, product0_.name as name2_1_ from product product0_
Hibernate: select company0_.id as id1_0_0_, company0_.name as name2_0_0_, products1_.company_id as company_3_1_1_, products1_.id as id1_1_1_, products1_.id as id1_1_2_, products1_.company_id as company_3_1_2_, products1_.name as name2_1_2_ from company company0_ left outer join product products1_ on company0_.id=products1_.company_id where company0_.id=?
Hibernate: select company0_.id as id1_0_0_, company0_.name as name2_0_0_, products1_.company_id as company_3_1_1_, products1_.id as id1_1_1_, products1_.id as id1_1_2_, products1_.company_id as company_3_1_2_, products1_.name as name2_1_2_ from company company0_ left outer join product products1_ on company0_.id=products1_.company_id where company0_.id=?
=====================Show All Products on console:====================
{"name":"Iphone 7","company":{"name":"Apple"}}
{"name":"IPadPro","company":{"name":"Apple"}}
{"name":"GalaxyJ7","company":{"name":"Samsung"}}
{"name":"GalaxyTabA","company":{"name":"Samsung"}}
|
7.2 Run with Lazy Fetch Type
Change the Fetch Type to LAZY for both: Company & Product.
– Company.java:
public class Company{
...
@OneToMany(mappedBy = "company", cascade = CascadeType.ALL, fetch = FetchType.LAZY)
...
1
2
3
4
5
|
...
public class Company{
...
@OneToMany(mappedBy = "company", cascade = CascadeType.ALL, fetch = FetchType.LAZY)
...
|
– Product.java:
public class Product{
...
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "company_id")
private Company company;
...
}
1
2
3
4
5
6
7
8
|
...
public class Product{
...
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "company_id")
private Company company;
...
}
|
– Build & Run again the project with SpringBoot App mode. – Logs:
Hibernate: select company0_.id as id1_0_, company0_.name as name2_0_ from company company0_
=====================Show All Companies on console:====================
Hibernate: select products0_.company_id as company_3_1_0_, products0_.id as id1_1_0_, products0_.id as id1_1_1_, products0_.company_id as company_3_1_1_, products0_.name as name2_1_1_ from product products0_ where products0_.company_id=?
{"name":"Apple","products":[{"name":"Iphone 7"},{"name":"IPadPro"}]}
Hibernate: select products0_.company_id as company_3_1_0_, products0_.id as id1_1_0_, products0_.id as id1_1_1_, products0_.company_id as company_3_1_1_, products0_.name as name2_1_1_ from product products0_ where products0_.company_id=?
{"name":"Samsung","products":[{"name":"GalaxyJ7"},{"name":"GalaxyTabA"}]}
=====================Retrieve Products from Database:====================
Hibernate: select product0_.id as id1_1_, product0_.company_id as company_3_1_, product0_.name as name2_1_ from product product0_
=====================Show All Products on console:====================
Hibernate: select company0_.id as id1_0_0_, company0_.name as name2_0_0_ from company company0_ where company0_.id=?
{"name":"Iphone 7","company":{"name":"Apple"}}
{"name":"IPadPro","company":{"name":"Apple"}}
Hibernate: select company0_.id as id1_0_0_, company0_.name as name2_0_0_ from company company0_ where company0_.id=?
{"name":"GalaxyJ7","company":{"name":"Samsung"}}
{"name":"GalaxyTabA","company":{"name":"Samsung"}}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|
=====================Retrieve Companies from Database:====================
Hibernate: select company0_.id as id1_0_, company0_.name as name2_0_ from company company0_
=====================Show All Companies on console:====================
Hibernate: select products0_.company_id as company_3_1_0_, products0_.id as id1_1_0_, products0_.id as id1_1_1_, products0_.company_id as company_3_1_1_, products0_.name as name2_1_1_ from product products0_ where products0_.company_id=?
{"name":"Apple","products":[{"name":"Iphone 7"},{"name":"IPadPro"}]}
Hibernate: select products0_.company_id as company_3_1_0_, products0_.id as id1_1_0_, products0_.id as id1_1_1_, products0_.company_id as company_3_1_1_, products0_.name as name2_1_1_ from product products0_ where products0_.company_id=?
{"name":"Samsung","products":[{"name":"GalaxyJ7"},{"name":"GalaxyTabA"}]}
=====================Retrieve Products from Database:====================
Hibernate: select product0_.id as id1_1_, product0_.company_id as company_3_1_, product0_.name as name2_1_ from product product0_
=====================Show All Products on console:====================
Hibernate: select company0_.id as id1_0_0_, company0_.name as name2_0_0_ from company company0_ where company0_.id=?
{"name":"Iphone 7","company":{"name":"Apple"}}
{"name":"IPadPro","company":{"name":"Apple"}}
Hibernate: select company0_.id as id1_0_0_, company0_.name as name2_0_0_ from company company0_ where company0_.id=?
{"name":"GalaxyJ7","company":{"name":"Samsung"}}
{"name":"GalaxyTabA","company":{"name":"Samsung"}}
|
7.3 Mix Lazy & Eager Fetch Types
Change fetch type: Company with FetchType.LAZY BUT Product with FetchType.EAGER.
– Company.java:
public class Company{
...
@OneToMany(mappedBy = "company", cascade = CascadeType.ALL, fetch = FetchType.LAZY)
...
1
2
3
4
5
|
...
public class Company{
...
@OneToMany(mappedBy = "company", cascade = CascadeType.ALL, fetch = FetchType.LAZY)
...
|
– Product.java:
public class Product{
...
@ManyToOne(fetch = FetchType.EAGER)
@JoinColumn(name = "company_id")
private Company company;
...
}
1
2
3
4
5
6
7
8
|
...
public class Product{
...
@ManyToOne(fetch = FetchType.EAGER)
@JoinColumn(name = "company_id")
private Company company;
...
}
|
Build & Run again the project with SpringBoot App mode.
– Logs:
Hibernate: select company0_.id as id1_0_, company0_.name as name2_0_ from company company0_
=====================Show All Companies on console:====================
Hibernate: select products0_.company_id as company_3_1_0_, products0_.id as id1_1_0_, products0_.id as id1_1_1_, products0_.company_id as company_3_1_1_, products0_.name as name2_1_1_ from product products0_ where products0_.company_id=?
{"name":"Apple","products":[{"name":"IPadPro"},{"name":"Iphone 7"}]}
Hibernate: select products0_.company_id as company_3_1_0_, products0_.id as id1_1_0_, products0_.id as id1_1_1_, products0_.company_id as company_3_1_1_, products0_.name as name2_1_1_ from product products0_ where products0_.company_id=?
{"name":"Samsung","products":[{"name":"GalaxyTabA"},{"name":"GalaxyJ7"}]}
=====================Retrieve Products from Database:====================
Hibernate: select product0_.id as id1_1_, product0_.company_id as company_3_1_, product0_.name as name2_1_ from product product0_
Hibernate: select company0_.id as id1_0_0_, company0_.name as name2_0_0_ from company company0_ where company0_.id=?
Hibernate: select company0_.id as id1_0_0_, company0_.name as name2_0_0_ from company company0_ where company0_.id=?
=====================Show All Products on console:====================
{"name":"Iphone 7","company":{"name":"Apple"}}
{"name":"IPadPro","company":{"name":"Apple"}}
{"name":"GalaxyJ7","company":{"name":"Samsung"}}
{"name":"GalaxyTabA","company":{"name":"Samsung"}}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|
=====================Retrieve Companies from Database:====================
Hibernate: select company0_.id as id1_0_, company0_.name as name2_0_ from company company0_
=====================Show All Companies on console:====================
Hibernate: select products0_.company_id as company_3_1_0_, products0_.id as id1_1_0_, products0_.id as id1_1_1_, products0_.company_id as company_3_1_1_, products0_.name as name2_1_1_ from product products0_ where products0_.company_id=?
{"name":"Apple","products":[{"name":"IPadPro"},{"name":"Iphone 7"}]}
Hibernate: select products0_.company_id as company_3_1_0_, products0_.id as id1_1_0_, products0_.id as id1_1_1_, products0_.company_id as company_3_1_1_, products0_.name as name2_1_1_ from product products0_ where products0_.company_id=?
{"name":"Samsung","products":[{"name":"GalaxyTabA"},{"name":"GalaxyJ7"}]}
=====================Retrieve Products from Database:====================
Hibernate: select product0_.id as id1_1_, product0_.company_id as company_3_1_, product0_.name as name2_1_ from product product0_
Hibernate: select company0_.id as id1_0_0_, company0_.name as name2_0_0_ from company company0_ where company0_.id=?
Hibernate: select company0_.id as id1_0_0_, company0_.name as name2_0_0_ from company company0_ where company0_.id=?
=====================Show All Products on console:====================
{"name":"Iphone 7","company":{"name":"Apple"}}
{"name":"IPadPro","company":{"name":"Apple"}}
{"name":"GalaxyJ7","company":{"name":"Samsung"}}
{"name":"GalaxyTabA","company":{"name":"Samsung"}}
|
IV. Sourcecode
SpringHibernateFetchType
By grokonez | April 27, 2017.