原帖 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:

 
 
@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(){
}
...
}

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:

CompanyServices.java

 
 
@Service
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:

 
 
=====================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"}]}
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:

Company.java

 
 
@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;
}
...
}

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:

 
 
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]
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

CompanyServices.java

 
 
@Service
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():

 
 
=====================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"}]}
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:

 
 
<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>
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

 
 
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;
}
}

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

 
 
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;
}
}

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

 
 
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>{
}

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

 
 
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>{
}

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:

 
 
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();
}
}

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:

 
 
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();
}
}

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.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

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

 
 
@Autowired
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 & productsaveData() 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:

 
 
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();
}

}

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:

 
 
=====================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"}}
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:

 
 
=====================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"}}
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:

 
 
=====================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"}}
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.

FW: How to use Hibernate Lazy Fetch and Eager Fetch Type – Spring Boot + MySQL的更多相关文章

  1. Hibernate - lazy, fetch, inverse, cascade

    Inverse是hibernate双向关系中的基本概念.inverse的真正作用就是指定由哪一方来维护之间的关联关系.当一方中指定了"inverse=false"(默认),那么那一 ...

  2. Hibernate -- lazy加载

    Hibernate -- lazy加载 hibernate类级别懒加载: lazy:true(默认) //类级别懒加载 //load方法 //class lazy属性 //默认值:true load获 ...

  3. about hibernate lazy load and solution

    about hibernate lazy load is that used when loaded again.it can increase efficienty and sava memory. ...

  4. Spring Boot 2.x 之 Spring Data JPA, Hibernate 5

    1. Spring Boot常用配置项 基于Spring Boot 2.0.6.RELEASE 1.1 配置属性类 spring.jpa前缀的相关配置项定义在JpaProperties类中, 1.2 ...

  5. 多对多关联懒加载导致failed to lazily initialize a collection of role: 实体类, could not initialize proxy - no Session 追加配置fetch = FetchType.EAGER解决

    一篇文章需要关联很多个标签,所以他们呈一对多(多对多)的关系 org.springframework.web.util.NestedServletException: Request processi ...

  6. 解决Mysql连接池被关闭 ,hibernate尝试连接不能连接的问题。 (默认mysql连接池可以访问的时间为8小时,如果超过8小时没有连接,mysql会自动关闭连接池。系统发布第二天访问链接关闭问题。

    解决Mysql连接池被关闭  ,hibernate尝试连接不能连接的问题. (默认MySQL连接池可以访问的时间为8小时,如果超过8小时没有连接,mysql会自动关闭连接池. 所以系统发布第二天访问会 ...

  7. org.hibernate.id.IdentifierGenerationException: Unknown integral data type for ids : java.lang.String

    org.hibernate.id.IdentifierGenerationException: Unknown integral data type for ids : java.lang.Strin ...

  8. org.hibernate.service.classloading.spi.ClassLoadingException: Specified JDBC Driver com.mysql.jdbc.Driver class not found

    今天在使用hibernate搭建开发环境的时候出现了一个不可思议的问题: org.hibernate.service.classloading.spi.ClassLoadingException: S ...

  9. spring boot 1.4默认使用 hibernate validator

    spring boot 1.4默认使用 hibernate validator 5.2.4 Final实现校验功能.hibernate validator 5.2.4 Final是JSR 349 Be ...

随机推荐

  1. idea的svn插件中compare with the same repository version和compare with latest repository version的区别?

    Idea的svn插件中compare with the same repository version和compare with latest repository version的区别? 1.com ...

  2. Malformed \uxxxx encoding

    今天碰到个问题. FATAL [btir.server.ServerStartup:54] - <java.lang.IllegalArgumentException: Malformed \u ...

  3. javaWeb中的文件上传下载

    在Web应用系统开发中,文件上传和下载功能是非常常用的功能,今天来讲一下JavaWeb中的文件上传和下载功能的实现. 对于文件上传,浏览器在上传的过程中是将文件以流的形式提交到服务器端的,如果直接使用 ...

  4. 最小树形图(hdu4009)

    Transfer water Time Limit: 5000/3000 MS (Java/Others)    Memory Limit: 65768/65768 K (Java/Others) T ...

  5. 学习认识Spring原理

    学习认识Spring原理 Spring 是一种业务层框架.搭建Spring框架需要Spring开发包和commons-logging包.Spring的核心思想是控制反转也称依赖注入(创建者--(实例) ...

  6. OA之框架的搭建

    1.使用框架可以有效的解决耦合性过高的问题,减少代码修改的程度,同时方便添加新的功能.首先创建出基本的几个类库.这个框架就是使用基本的逻辑分层三层架构,然后进一步再使用接口对每个逻辑中的类库调用进行解 ...

  7. poj2411 Mondriaan's Dream【状压DP】

    Mondriaan's Dream Time Limit: 3000MS   Memory Limit: 65536K Total Submissions: 20822   Accepted: 117 ...

  8. mongdb ---shard

    http://blog.fens.me/mongodb-shard/ https://segmentfault.com/a/1190000004263332 1. 和用户管理相关的操作基本都要在adm ...

  9. 模拟百度云盘版的ftp

    思路:一.分两个大的文件夹,一个是客户端,一个服务端的 二.实现的功能 1.    登陆--对用户名的合法性进行检测(实验账户:alex,123)                注册--设置账户,其中 ...

  10. HTTP返回码中301与302的区别(转)

    add by zhj:  区别 1.使用效果不同 302跳转是暂时的跳转,搜索引擎会抓取新的内容而保留旧的网址.因为服务器返回302代码,搜索引擎认为新的网址只是暂时的. 301重定向是永久的重定向, ...