際際滷

際際滷Share a Scribd company logo
Hibernate Fetch Strategies,
   N+1 Select Problem


                          1
Topics
   Fetching strategies
   Types of fetching strategies
       How fetching is done
       When fetching is done
   N+1 select problem
       Factors that influence number of select statements
       Various examples
   Recommendation


                                                             2
Fetching Strategies

                      3
What is a Fetching Strategy?
   A fetching strategy is the strategy Hibernate will
    use for retrieving associated objects if the
    application needs to navigate the association.
   Fetching strategy will have performance impact
   Fetch strategies may be declared in the
    mapping files, or over-ridden by a particular
    HQL or Criteria query.




                                                     4
Types of Fetching Strategies
   How fetching is done
       Join
       Select (default)
       Subselect
       Batch
   When fetching is done
       immediate
       lazy (default)



                               5
Fetching Strategies:
How Fetching is Done
                        6
Join Fetching
   Hibernate retrieves the associated instance or
    collection in the same SELECT, using an
    OUTER JOIN




                                                     7
Join Fetching in HQL

String hql = "from Product p join fetch p.supplier as s";
Query query = session.createQuery(hql);
List results = query.list();




                                                       8
Join Fetching in Criteria API

Criteria crit = session.createCriteria(Product.class);
crit.setFetchMode("supplier", FetchMode.JOIN);
List results = crit.list();




                                                         9
Select Fetching
   Default fetch mode
   Vulnerable to N+1 selects problem
       N number of SELECT's are used to retrieve the
        associated entity or collection.
   Unless you explicitly disable lazy fetching by
    specifying lazy="false", the subsequent select
    will only be executed when you actually access
    the association.



                                                          10
Subselect Fetching
   A second SELECT is used to retrieve the
    associated collections for all entities retrieved in
    a previous query or fetch.
   Unless you explicitly disable lazy fetching by
    specifying lazy="false", this second select will
    only be executed when you actually access the
    association.




                                                       11
Batch Fetching
   An optimization strategy for select fetching -
    Hibernate retrieves a batch of entity instances or
    collections in a single SELECT, by specifying a
    list of primary keys or foreign keys.




                                                    12
Tuning fetch strategies
   Select fetching (the default) is extremely
    vulnerable to N+1 selects problems, so you
    might want to enable join fetching in the
    mapping document:

    <set name="permissions"
           fetch="join">
      <key column="userId"/>
      <one-to-many class="Permission"/>
    </set

                                                 13
Fetching Strategies:
When Fetching is Done
                        14
Lazy Fetching
   A collection is fetched when the application
    invokes an operation upon that collection
   Default for collections




                                                   15
N+1 Select
 Problem
             16
Example Scenario
   Supplier with a one-to-many relationship with
    Product.
       One Supplier has (supplies) many Products




                                                    17
Example Data
*** Table: Supplier **
+-------------+----------------------+
|    ID |           NAME             |
+-------------+----------------------+
|1          | Supplier Name 1            |
|2          | Supplier Name 2            |
|3          | Supplier Name 3            |
|4          | Supplier Name 4            |
+-------------+----------------------+

*** Table: Product **
+-------------+----------------------+--------------------------------+------------------------+--------------------+
|    ID |           NAME             |       DESCRIPTION                  |        PRICE | SUPPLIERID |
+-------------+----------------------+--------------------------------+------------------------+--------------------+
|1          | Product 1             | Name for Product 1                 | 2.0                 |1                   |
|2          | Product 2             | Name for Product 2                 | 22.0                |1                   |
|3          | Product 3             | Name for Product 3                 | 30.0                |2                   |
|4          | Product 4             | Name for Product 4                 | 7.0                 |3                   |
+-------------+----------------------+--------------------------------+------------------------+--------------------+



                                                                                                                        18
Factors that influence number of
select statements
   When fetching is done
       lazy mode for Supplier
   How fetching is done
       Fetch mode used for querying on Product
       Select vs. Join
   Whether Supplier is accessed through Product or
    not
   Caching
       Whether Supplier is cached or now


                                                  19
Hands-on Lab Exercises
1.LazyTrue-SelectFetch-SupplierNotAccessed
2.LazyTrue-SelectFetch-SupplierAccessed
3.LazyFalse-SelectFetch-SupplierNotAccessed
4.LazyFalse-SelectFetch-SupplierAccessed
5.LazyTrue-JoinFetch-SupplierNotAccessed
6.LazyTrue-JoinFetch-SupplierAccessed
7.LazyFalse-JoinFetch-SupplierNotAccessed
8.LazyFalse-JoinFetch-SupplierAccessed


                                              20
Hands-on Lab Exercises
9.LazyFalse-JoinFetchLeftOuter-SupplierAccessed
10.LazyFalse-JoinFetchRightOuter-SupplierAccessed




                                             21
Example #1
LazyTrue-SelectFetch-
SupplierNotAccessed


                        22
Example #1
   Factors
       lazy mode for Supplier set to true (default)
       Fetch mode used for querying on Product is Select
        fetch mode (default)
       Supplier information is not accessed
       Caching does not play a role for the first time the
        Supplier is accessed
   Sample project in the hands-on lab
       01HibernateHQLQuery-LazyTrue-SelectFetch-
        SupplierNotAccessed


                                                              23
Supplier.hbm.xml: lazy=true
<hibernate-mapping>
 <!-- lazy attribute is not set so it takes the default value of true -->
 <class name="Supplier">
    <id name="id" type="int">
      <generator class="increment"/>
    </id>

    <property name="name" type="string"/>
    <bag name="products" inverse="true" cascade="all,delete-
  orphan">
      <key column="supplierId"/>
      <one-to-many class="Product"/>
    </bag>

  </class>
</hibernate-mapping>                                                  24
Fetch mode is Select Fetch (default)
 // It takes Select fetch mode as a default
  Query query = session.createQuery( "from Product p");
  List list = query.list();

 // Supplier is not being accessed
 displayProductsListWithoutSupplierName(results);




                                                      25
Supplier is not accessed
public static void displayProductsListWithoutSupplierName(List list){
     Iterator iter = list.iterator();
     if (!iter.hasNext()){
         System.out.println("No products to display.");
         return;
     }
     while (iter.hasNext()){
         Product product = (Product) iter.next();
         // String msg = product.getSupplier().getName() + "t";
         String msg = "t";
         msg += product.getName() + "t";
         msg += product.getPrice() + "t";
         msg += product.getDescription();
         System.out.println(msg);
     }
  }
                                                                        26
Number of Select Statements
select ... various field names ... from PRODUCT

   1 select statement for Product
   Delayed N+1 select problem, however, since
    Supplier is not accessed for now




                                                  27
Example #2
LazyTrue-SelectFetch-
  SupplierAccessed


                        28
Example #2
   Factors
       lazy mode for Supplier set to true (default)
       Fetch mode used for querying on Product is Select
        fetch mode (default)
       Supplier information is accessed
       Caching does not play a role for the first time the
        Supplier is accessed
   Sample project in the hands-on lab
       02HibernateHQLQuery-LazyTrue-SelectFetch-
        SupplierAccessed


                                                              29
Fetch mode is Select Fetch (default)
 // It takes Select fetch mode as a default
  Query query = session.createQuery( "from Product p");
  List list = query.list();

 // Supplier is being accessed
 displayProductsListWithSupplierName(results);




                                                      30
Supplier is accessed
public static void displayProductsListWithSupplierName(List list){
     Iterator iter = list.iterator();
     if (!iter.hasNext()){
         System.out.println("No products to display.");
         return;
     }
     while (iter.hasNext()){
         Product product = (Product) iter.next();
         String msg = product.getSupplier().getName() + "t";
         String msg = "t";
         msg += product.getName() + "t";
         msg += product.getPrice() + "t";
         msg += product.getDescription();
         System.out.println(msg);
     }
  }
                                                                     31
Select Statements Used

select ... various field names ... from PRODUCT
select ... various field names ... from SUPPLIER where SUPPLIER.id=?
select ... various field names ... from SUPPLIER where SUPPLIER.id=?
select ... various field names ... from SUPPLIER where SUPPLIER.id=?


   Result
       1 select statement for Product
       N select statements for Supplier
   This is N+1 select problem!

                                                                32
Example #3
LazyFalse-SelectFetch-
  SupplierAccessed


                         33
Example Scenario #3
   Factors
       lazy mode for Supplier set to false
       Fetch mode used for querying on Product is Select
        fetch mode (default)
       Supplier information is not accessed
       Caching does not play a role for the first time the
        Supplier is accessed
   Sample project in the hands-on lab
       03HibernateHQLQuery-LazyFase-SelectFetch-
        SupplierNotAccessed


                                                              34
Supplier.hbm.xml: lazy=false
<hibernate-mapping>

 <class name="Supplier" lazy="false">
   <id name="id" type="int">
     <generator class="increment"/>
   </id>

   <property name="name" type="string"/>
   <bag name="products" inverse="true" cascade="all,delete-
 orphan">
     <key column="supplierId"/>
     <one-to-many class="Product"/>
   </bag>

  </class>
</hibernate-mapping>
                                                              35
Fetch mode is Select Fetch (default)
 // It takes Select fetch mode as a default
  Query query = session.createQuery( "from Product p");
  List list = query.list();

 // Supplier is not being accessed
 displayProductsListWithoutSupplierName(results);




                                                      36
Select Statements Used
select ... various field names ... from PRODUCT
select ... various field names ... from SUPPLIER where SUPPLIER.id=?
select ... various field names ... from SUPPLIER where SUPPLIER.id=?
select ... various field names ... from SUPPLIER where SUPPLIER.id=?


   Result
       1 select statement for Product
       N select statements for Supplier
   This is N+1 select problem!
       Even though Supplier is not accessed, because lazy is
        set to false, N select statements are used to access
        Supplier
                                                                37
Example #4
LazyFalse-SelectFetch-
 SupplierNotAccessed


                         38
Example Scenario #4
   Factors
       lazy mode for Supplier set to false
       Fetch mode used for querying on Product is Select
        fetch mode (default)
       Supplier information is accessed
       Caching does not play a role for the first time the
        Supplier is accessed
   Sample project in the hands-on lab
       04HibernateHQLQuery-LazyFase-SelectFetch-
        SupplierAccessed


                                                              39
Select Statements Used
select ... various field names ... from PRODUCT
select ... various field names ... from SUPPLIER where SUPPLIER.id=?
select ... various field names ... from SUPPLIER where SUPPLIER.id=?
select ... various field names ... from SUPPLIER where SUPPLIER.id=?


   Result
       1 select statement for Product
       N select statements for Supplier
   This is N+1 select problem!
       Even though Supplier is not accessed, because lazy is
        set to false, N select statements are used to access
        Supplier
                                                                40
Example #5
LazyTrue-JoinFetch-
SupplierNotAccessed


                      41
Example #5
   Factors
       lazy mode for Supplier set to true (default)
       Fetch mode used for querying on Product is Join fetch
        mode
       Supplier information is not accessed
       Caching does not play a role for the first time the
        Supplier is accessed
   Sample project in the hands-on lab
       05HibernateHQLQuery-LazyTrue-JoinFetch-
        SupplierNotAccessed


                                                           42
Fetch mode is Join Fetch
 // Perform Join Fetch
  String hql = "from Product p join fetch p.supplier as s";
  Query query = session.createQuery(hql);
  List results = query.list();

 // Supplier is not being accessed
 displayProductsListWithoutSupplierName(results);




                                                              43
Number of Select Statements

select ... various field names from Product product0_ inner join
  Supplier supplier1_ on product0_.supplierId=supplier1_.id

   1 inner join select statement
   No N+1 select problem




                                                               44
Example #6
LazyTrue-JoinFetch-
 SupplierAccessed


                      45
Example #6
   Factors
       lazy mode for Supplier set to true (default)
       Fetch mode used for querying on Product is Join fetch
        mode
       Supplier information is accessed
       Caching does not play a role for the first time the
        Supplier is accessed
   Sample project in the hands-on lab
       06HibernateHQLQuery-LazyTrue-JoinFetch-
        SupplierAccessed


                                                           46
Fetch mode is Join Fetch
 // Perform Join Fetch
  String hql = "from Product p join fetch p.supplier as s";
  Query query = session.createQuery(hql);
  List results = query.list();

 // Supplier is being accessed
 displayProductsListWithSupplierName(results);




                                                              47
Number of Select Statements

select ... various field names from Product product0_ inner join
  Supplier supplier1_ on product0_.supplierId=supplier1_.id

   1 inner join select statement
   No N+1 select problem




                                                               48
Example #7
LazyFalse-JoinFetch-
SupplierNotAccessed


                       49
Example #7
   Factors
       lazy mode for Supplier set to false
       Fetch mode used for querying on Product is Join fetch
        mode
       Supplier information is not accessed
       Caching does not play a role for the first time the
        Supplier is accessed
   Sample project in the hands-on lab
       07HibernateHQLQuery-LazyFalse-JoinFetch-
        SupplierNotAccessed


                                                           50
Number of Select Statements

select ... various field names from Product product0_ inner join
  Supplier supplier1_ on product0_.supplierId=supplier1_.id

   1 inner join select statement
   No N+1 select problem




                                                               51
Example #8
LazyFalse-JoinFetch-
 SupplierAccessed


                       52
Example #8
   Factors
       lazy mode for Supplier set to false
       Fetch mode used for querying on Product is Join fetch
        mode
       Supplier information is accessed
       Caching does not play a role for the first time the
        Supplier is accessed
   Sample project in the hands-on lab
       08HibernateHQLQuery-LazyFalse-JoinFetch-
        SupplierAccessed


                                                           53
Number of Select Statements

select ... various field names from Product product0_ inner join
  Supplier supplier1_ on product0_.supplierId=supplier1_.id

   1 inner join select statement
   No N+1 select problem




                                                               54
Example #9
  LazyTrue-SelectFetch-
SupplierAccessed-Caching


                           55
Example #2
   Factors
       lazy mode for Supplier set to true (default)
       Fetch mode used for querying on Product is Select
        fetch mode (default)
       Supplier information is accessed
       Caching play a role the Supplier is accessed the
        second time
   Sample project in the hands-on lab
       HibernateHQLQuery-LazyTrue-SelectFetch-
        SupplierAccessed-Caching


                                                            56
Access Supplier Through Cache
System.out.println("n---Performing HQL query with LazyTrue-SelectFetch-SupplierAccessed..."
Query query = session.createQuery("from Product");
List results = query.list();
displayProductsListWithSupplierName(results);

System.out.println("n---Performing HQL query using Cache...");
Query query = session.createQuery("from Product");
List results = query.list();
displayProductsListWithSupplierName(results);

// Clear cache
session.clear();
System.out.println("n---Performing HQL query after clearing Cache...");
Query query = session.createQuery("from Product");
List results = query.list();
displayProductsListWithSupplierName(results);



                                                                                  57
Select Statements Used
select ... various field names ... from PRODUCT
select ... various field names ... from SUPPLIER where SUPPLIER.id=?
select ... various field names ... from SUPPLIER where SUPPLIER.id=?
select ... various field names ... from SUPPLIER where SUPPLIER.id=?


select ... various field names ... from PRODUCT


select ... various field names ... from PRODUCT
select ... various field names ... from SUPPLIER where SUPPLIER.id=?
select ... various field names ... from SUPPLIER where SUPPLIER.id=?
select ... various field names ... from SUPPLIER where SUPPLIER.id=?



                                                                       58
Fetching Strategies:
 Recommendations
                       59
Recommendation
   Join fetching is good for small collection of child
    objects often used with parent
   Large collections and/or not always used
    collections are better retrieved with lazy select
    fetching




                                                          60
Hibernate Fetch Strategies,
   N+1 Select Problem


                          61

More Related Content

Similar to Hibernatejoinfetch (20)

Understanding GBM and XGBoost in Scikit-Learn
Understanding GBM and XGBoost in Scikit-LearnUnderstanding GBM and XGBoost in Scikit-Learn
Understanding GBM and XGBoost in Scikit-Learn
豌覩 蟠
Sumo Logic Cert Jam - Fundamentals
Sumo Logic Cert Jam - FundamentalsSumo Logic Cert Jam - Fundamentals
Sumo Logic Cert Jam - Fundamentals
Sumo Logic
L14: Access Rights and Triggers
L14: Access Rights and TriggersL14: Access Rights and Triggers
L14: Access Rights and Triggers
medialeg gmbh
Big Data Analytics using Mahout
Big Data Analytics using MahoutBig Data Analytics using Mahout
Big Data Analytics using Mahout
IMC Institute
Filtering data in google spreadsheets - Short tutorials
Filtering data in google spreadsheets - Short tutorialsFiltering data in google spreadsheets - Short tutorials
Filtering data in google spreadsheets - Short tutorials
lenorajohnson
Machine learning Algorithms with a Sagemaker demo
Machine learning Algorithms with a Sagemaker demoMachine learning Algorithms with a Sagemaker demo
Machine learning Algorithms with a Sagemaker demo
Hridyesh Bisht
Modular and Extensible Extract Method. Talk from ESUG 2024
Modular and Extensible Extract Method. Talk from ESUG 2024Modular and Extensible Extract Method. Talk from ESUG 2024
Modular and Extensible Extract Method. Talk from ESUG 2024
ESUG
Building a Pyramid: Symfony Testing Strategies
Building a Pyramid: Symfony Testing StrategiesBuilding a Pyramid: Symfony Testing Strategies
Building a Pyramid: Symfony Testing Strategies
CiaranMcNulty
Extending MariaDB with user-defined functions
Extending MariaDB with user-defined functionsExtending MariaDB with user-defined functions
Extending MariaDB with user-defined functions
MariaDB plc
Apache Calcite Tutorial - BOSS 21
Apache Calcite Tutorial - BOSS 21Apache Calcite Tutorial - BOSS 21
Apache Calcite Tutorial - BOSS 21
Stamatis Zampetakis
2006 - Basta!: Advanced server controls
2006 - Basta!: Advanced server controls2006 - Basta!: Advanced server controls
2006 - Basta!: Advanced server controls
Daniel Fisher
The Ring programming language version 1.5.2 book - Part 9 of 181
The Ring programming language version 1.5.2 book - Part 9 of 181The Ring programming language version 1.5.2 book - Part 9 of 181
The Ring programming language version 1.5.2 book - Part 9 of 181
Mahmoud Samir Fayed
Open Source ERP Technologies for Java Developers
Open Source ERP Technologies for Java DevelopersOpen Source ERP Technologies for Java Developers
Open Source ERP Technologies for Java Developers
cboecking
Automated integration tests for ajax applications (. 从舒仗亳仆, auriga)
Automated integration tests for ajax applications (. 从舒仗亳仆, auriga)Automated integration tests for ajax applications (. 从舒仗亳仆, auriga)
Automated integration tests for ajax applications (. 从舒仗亳仆, auriga)
Mobile Developer Day
Testing Spring Applications
Testing Spring ApplicationsTesting Spring Applications
Testing Spring Applications
Muhammad Abdullah
Most Advanced GTM Deployment. Ever!
Most Advanced GTM Deployment. Ever!Most Advanced GTM Deployment. Ever!
Most Advanced GTM Deployment. Ever!
Phil Pearce
Applying TDD to Legacy Code
Applying TDD to Legacy CodeApplying TDD to Legacy Code
Applying TDD to Legacy Code
Alexander Goida
Demonstration of climate-smart agriculture prioritisation toolkit
Demonstration of climate-smart agriculture prioritisation toolkit Demonstration of climate-smart agriculture prioritisation toolkit
Demonstration of climate-smart agriculture prioritisation toolkit
CCAFS | CGIAR Research Program on Climate Change, Agriculture and Food Security
TechDays 2016 - Developing websites using asp.net core mvc6 and entity framew...
TechDays 2016 - Developing websites using asp.net core mvc6 and entity framew...TechDays 2016 - Developing websites using asp.net core mvc6 and entity framew...
TechDays 2016 - Developing websites using asp.net core mvc6 and entity framew...
Fons Sonnemans
Machine Learning Crash Course by Sebastian Raschka
Machine Learning Crash Course by Sebastian RaschkaMachine Learning Crash Course by Sebastian Raschka
Machine Learning Crash Course by Sebastian Raschka
PawanJayarathna1
Understanding GBM and XGBoost in Scikit-Learn
Understanding GBM and XGBoost in Scikit-LearnUnderstanding GBM and XGBoost in Scikit-Learn
Understanding GBM and XGBoost in Scikit-Learn
豌覩 蟠
Sumo Logic Cert Jam - Fundamentals
Sumo Logic Cert Jam - FundamentalsSumo Logic Cert Jam - Fundamentals
Sumo Logic Cert Jam - Fundamentals
Sumo Logic
L14: Access Rights and Triggers
L14: Access Rights and TriggersL14: Access Rights and Triggers
L14: Access Rights and Triggers
medialeg gmbh
Big Data Analytics using Mahout
Big Data Analytics using MahoutBig Data Analytics using Mahout
Big Data Analytics using Mahout
IMC Institute
Filtering data in google spreadsheets - Short tutorials
Filtering data in google spreadsheets - Short tutorialsFiltering data in google spreadsheets - Short tutorials
Filtering data in google spreadsheets - Short tutorials
lenorajohnson
Machine learning Algorithms with a Sagemaker demo
Machine learning Algorithms with a Sagemaker demoMachine learning Algorithms with a Sagemaker demo
Machine learning Algorithms with a Sagemaker demo
Hridyesh Bisht
Modular and Extensible Extract Method. Talk from ESUG 2024
Modular and Extensible Extract Method. Talk from ESUG 2024Modular and Extensible Extract Method. Talk from ESUG 2024
Modular and Extensible Extract Method. Talk from ESUG 2024
ESUG
Building a Pyramid: Symfony Testing Strategies
Building a Pyramid: Symfony Testing StrategiesBuilding a Pyramid: Symfony Testing Strategies
Building a Pyramid: Symfony Testing Strategies
CiaranMcNulty
Extending MariaDB with user-defined functions
Extending MariaDB with user-defined functionsExtending MariaDB with user-defined functions
Extending MariaDB with user-defined functions
MariaDB plc
Apache Calcite Tutorial - BOSS 21
Apache Calcite Tutorial - BOSS 21Apache Calcite Tutorial - BOSS 21
Apache Calcite Tutorial - BOSS 21
Stamatis Zampetakis
2006 - Basta!: Advanced server controls
2006 - Basta!: Advanced server controls2006 - Basta!: Advanced server controls
2006 - Basta!: Advanced server controls
Daniel Fisher
The Ring programming language version 1.5.2 book - Part 9 of 181
The Ring programming language version 1.5.2 book - Part 9 of 181The Ring programming language version 1.5.2 book - Part 9 of 181
The Ring programming language version 1.5.2 book - Part 9 of 181
Mahmoud Samir Fayed
Open Source ERP Technologies for Java Developers
Open Source ERP Technologies for Java DevelopersOpen Source ERP Technologies for Java Developers
Open Source ERP Technologies for Java Developers
cboecking
Automated integration tests for ajax applications (. 从舒仗亳仆, auriga)
Automated integration tests for ajax applications (. 从舒仗亳仆, auriga)Automated integration tests for ajax applications (. 从舒仗亳仆, auriga)
Automated integration tests for ajax applications (. 从舒仗亳仆, auriga)
Mobile Developer Day
Testing Spring Applications
Testing Spring ApplicationsTesting Spring Applications
Testing Spring Applications
Muhammad Abdullah
Most Advanced GTM Deployment. Ever!
Most Advanced GTM Deployment. Ever!Most Advanced GTM Deployment. Ever!
Most Advanced GTM Deployment. Ever!
Phil Pearce
Applying TDD to Legacy Code
Applying TDD to Legacy CodeApplying TDD to Legacy Code
Applying TDD to Legacy Code
Alexander Goida
TechDays 2016 - Developing websites using asp.net core mvc6 and entity framew...
TechDays 2016 - Developing websites using asp.net core mvc6 and entity framew...TechDays 2016 - Developing websites using asp.net core mvc6 and entity framew...
TechDays 2016 - Developing websites using asp.net core mvc6 and entity framew...
Fons Sonnemans
Machine Learning Crash Course by Sebastian Raschka
Machine Learning Crash Course by Sebastian RaschkaMachine Learning Crash Course by Sebastian Raschka
Machine Learning Crash Course by Sebastian Raschka
PawanJayarathna1

Hibernatejoinfetch

  • 1. Hibernate Fetch Strategies, N+1 Select Problem 1
  • 2. Topics Fetching strategies Types of fetching strategies How fetching is done When fetching is done N+1 select problem Factors that influence number of select statements Various examples Recommendation 2
  • 4. What is a Fetching Strategy? A fetching strategy is the strategy Hibernate will use for retrieving associated objects if the application needs to navigate the association. Fetching strategy will have performance impact Fetch strategies may be declared in the mapping files, or over-ridden by a particular HQL or Criteria query. 4
  • 5. Types of Fetching Strategies How fetching is done Join Select (default) Subselect Batch When fetching is done immediate lazy (default) 5
  • 7. Join Fetching Hibernate retrieves the associated instance or collection in the same SELECT, using an OUTER JOIN 7
  • 8. Join Fetching in HQL String hql = "from Product p join fetch p.supplier as s"; Query query = session.createQuery(hql); List results = query.list(); 8
  • 9. Join Fetching in Criteria API Criteria crit = session.createCriteria(Product.class); crit.setFetchMode("supplier", FetchMode.JOIN); List results = crit.list(); 9
  • 10. Select Fetching Default fetch mode Vulnerable to N+1 selects problem N number of SELECT's are used to retrieve the associated entity or collection. Unless you explicitly disable lazy fetching by specifying lazy="false", the subsequent select will only be executed when you actually access the association. 10
  • 11. Subselect Fetching A second SELECT is used to retrieve the associated collections for all entities retrieved in a previous query or fetch. Unless you explicitly disable lazy fetching by specifying lazy="false", this second select will only be executed when you actually access the association. 11
  • 12. Batch Fetching An optimization strategy for select fetching - Hibernate retrieves a batch of entity instances or collections in a single SELECT, by specifying a list of primary keys or foreign keys. 12
  • 13. Tuning fetch strategies Select fetching (the default) is extremely vulnerable to N+1 selects problems, so you might want to enable join fetching in the mapping document: <set name="permissions" fetch="join"> <key column="userId"/> <one-to-many class="Permission"/> </set 13
  • 15. Lazy Fetching A collection is fetched when the application invokes an operation upon that collection Default for collections 15
  • 17. Example Scenario Supplier with a one-to-many relationship with Product. One Supplier has (supplies) many Products 17
  • 18. Example Data *** Table: Supplier ** +-------------+----------------------+ | ID | NAME | +-------------+----------------------+ |1 | Supplier Name 1 | |2 | Supplier Name 2 | |3 | Supplier Name 3 | |4 | Supplier Name 4 | +-------------+----------------------+ *** Table: Product ** +-------------+----------------------+--------------------------------+------------------------+--------------------+ | ID | NAME | DESCRIPTION | PRICE | SUPPLIERID | +-------------+----------------------+--------------------------------+------------------------+--------------------+ |1 | Product 1 | Name for Product 1 | 2.0 |1 | |2 | Product 2 | Name for Product 2 | 22.0 |1 | |3 | Product 3 | Name for Product 3 | 30.0 |2 | |4 | Product 4 | Name for Product 4 | 7.0 |3 | +-------------+----------------------+--------------------------------+------------------------+--------------------+ 18
  • 19. Factors that influence number of select statements When fetching is done lazy mode for Supplier How fetching is done Fetch mode used for querying on Product Select vs. Join Whether Supplier is accessed through Product or not Caching Whether Supplier is cached or now 19
  • 23. Example #1 Factors lazy mode for Supplier set to true (default) Fetch mode used for querying on Product is Select fetch mode (default) Supplier information is not accessed Caching does not play a role for the first time the Supplier is accessed Sample project in the hands-on lab 01HibernateHQLQuery-LazyTrue-SelectFetch- SupplierNotAccessed 23
  • 24. Supplier.hbm.xml: lazy=true <hibernate-mapping> <!-- lazy attribute is not set so it takes the default value of true --> <class name="Supplier"> <id name="id" type="int"> <generator class="increment"/> </id> <property name="name" type="string"/> <bag name="products" inverse="true" cascade="all,delete- orphan"> <key column="supplierId"/> <one-to-many class="Product"/> </bag> </class> </hibernate-mapping> 24
  • 25. Fetch mode is Select Fetch (default) // It takes Select fetch mode as a default Query query = session.createQuery( "from Product p"); List list = query.list(); // Supplier is not being accessed displayProductsListWithoutSupplierName(results); 25
  • 26. Supplier is not accessed public static void displayProductsListWithoutSupplierName(List list){ Iterator iter = list.iterator(); if (!iter.hasNext()){ System.out.println("No products to display."); return; } while (iter.hasNext()){ Product product = (Product) iter.next(); // String msg = product.getSupplier().getName() + "t"; String msg = "t"; msg += product.getName() + "t"; msg += product.getPrice() + "t"; msg += product.getDescription(); System.out.println(msg); } } 26
  • 27. Number of Select Statements select ... various field names ... from PRODUCT 1 select statement for Product Delayed N+1 select problem, however, since Supplier is not accessed for now 27
  • 28. Example #2 LazyTrue-SelectFetch- SupplierAccessed 28
  • 29. Example #2 Factors lazy mode for Supplier set to true (default) Fetch mode used for querying on Product is Select fetch mode (default) Supplier information is accessed Caching does not play a role for the first time the Supplier is accessed Sample project in the hands-on lab 02HibernateHQLQuery-LazyTrue-SelectFetch- SupplierAccessed 29
  • 30. Fetch mode is Select Fetch (default) // It takes Select fetch mode as a default Query query = session.createQuery( "from Product p"); List list = query.list(); // Supplier is being accessed displayProductsListWithSupplierName(results); 30
  • 31. Supplier is accessed public static void displayProductsListWithSupplierName(List list){ Iterator iter = list.iterator(); if (!iter.hasNext()){ System.out.println("No products to display."); return; } while (iter.hasNext()){ Product product = (Product) iter.next(); String msg = product.getSupplier().getName() + "t"; String msg = "t"; msg += product.getName() + "t"; msg += product.getPrice() + "t"; msg += product.getDescription(); System.out.println(msg); } } 31
  • 32. Select Statements Used select ... various field names ... from PRODUCT select ... various field names ... from SUPPLIER where SUPPLIER.id=? select ... various field names ... from SUPPLIER where SUPPLIER.id=? select ... various field names ... from SUPPLIER where SUPPLIER.id=? Result 1 select statement for Product N select statements for Supplier This is N+1 select problem! 32
  • 33. Example #3 LazyFalse-SelectFetch- SupplierAccessed 33
  • 34. Example Scenario #3 Factors lazy mode for Supplier set to false Fetch mode used for querying on Product is Select fetch mode (default) Supplier information is not accessed Caching does not play a role for the first time the Supplier is accessed Sample project in the hands-on lab 03HibernateHQLQuery-LazyFase-SelectFetch- SupplierNotAccessed 34
  • 35. Supplier.hbm.xml: lazy=false <hibernate-mapping> <class name="Supplier" lazy="false"> <id name="id" type="int"> <generator class="increment"/> </id> <property name="name" type="string"/> <bag name="products" inverse="true" cascade="all,delete- orphan"> <key column="supplierId"/> <one-to-many class="Product"/> </bag> </class> </hibernate-mapping> 35
  • 36. Fetch mode is Select Fetch (default) // It takes Select fetch mode as a default Query query = session.createQuery( "from Product p"); List list = query.list(); // Supplier is not being accessed displayProductsListWithoutSupplierName(results); 36
  • 37. Select Statements Used select ... various field names ... from PRODUCT select ... various field names ... from SUPPLIER where SUPPLIER.id=? select ... various field names ... from SUPPLIER where SUPPLIER.id=? select ... various field names ... from SUPPLIER where SUPPLIER.id=? Result 1 select statement for Product N select statements for Supplier This is N+1 select problem! Even though Supplier is not accessed, because lazy is set to false, N select statements are used to access Supplier 37
  • 39. Example Scenario #4 Factors lazy mode for Supplier set to false Fetch mode used for querying on Product is Select fetch mode (default) Supplier information is accessed Caching does not play a role for the first time the Supplier is accessed Sample project in the hands-on lab 04HibernateHQLQuery-LazyFase-SelectFetch- SupplierAccessed 39
  • 40. Select Statements Used select ... various field names ... from PRODUCT select ... various field names ... from SUPPLIER where SUPPLIER.id=? select ... various field names ... from SUPPLIER where SUPPLIER.id=? select ... various field names ... from SUPPLIER where SUPPLIER.id=? Result 1 select statement for Product N select statements for Supplier This is N+1 select problem! Even though Supplier is not accessed, because lazy is set to false, N select statements are used to access Supplier 40
  • 42. Example #5 Factors lazy mode for Supplier set to true (default) Fetch mode used for querying on Product is Join fetch mode Supplier information is not accessed Caching does not play a role for the first time the Supplier is accessed Sample project in the hands-on lab 05HibernateHQLQuery-LazyTrue-JoinFetch- SupplierNotAccessed 42
  • 43. Fetch mode is Join Fetch // Perform Join Fetch String hql = "from Product p join fetch p.supplier as s"; Query query = session.createQuery(hql); List results = query.list(); // Supplier is not being accessed displayProductsListWithoutSupplierName(results); 43
  • 44. Number of Select Statements select ... various field names from Product product0_ inner join Supplier supplier1_ on product0_.supplierId=supplier1_.id 1 inner join select statement No N+1 select problem 44
  • 46. Example #6 Factors lazy mode for Supplier set to true (default) Fetch mode used for querying on Product is Join fetch mode Supplier information is accessed Caching does not play a role for the first time the Supplier is accessed Sample project in the hands-on lab 06HibernateHQLQuery-LazyTrue-JoinFetch- SupplierAccessed 46
  • 47. Fetch mode is Join Fetch // Perform Join Fetch String hql = "from Product p join fetch p.supplier as s"; Query query = session.createQuery(hql); List results = query.list(); // Supplier is being accessed displayProductsListWithSupplierName(results); 47
  • 48. Number of Select Statements select ... various field names from Product product0_ inner join Supplier supplier1_ on product0_.supplierId=supplier1_.id 1 inner join select statement No N+1 select problem 48
  • 50. Example #7 Factors lazy mode for Supplier set to false Fetch mode used for querying on Product is Join fetch mode Supplier information is not accessed Caching does not play a role for the first time the Supplier is accessed Sample project in the hands-on lab 07HibernateHQLQuery-LazyFalse-JoinFetch- SupplierNotAccessed 50
  • 51. Number of Select Statements select ... various field names from Product product0_ inner join Supplier supplier1_ on product0_.supplierId=supplier1_.id 1 inner join select statement No N+1 select problem 51
  • 53. Example #8 Factors lazy mode for Supplier set to false Fetch mode used for querying on Product is Join fetch mode Supplier information is accessed Caching does not play a role for the first time the Supplier is accessed Sample project in the hands-on lab 08HibernateHQLQuery-LazyFalse-JoinFetch- SupplierAccessed 53
  • 54. Number of Select Statements select ... various field names from Product product0_ inner join Supplier supplier1_ on product0_.supplierId=supplier1_.id 1 inner join select statement No N+1 select problem 54
  • 55. Example #9 LazyTrue-SelectFetch- SupplierAccessed-Caching 55
  • 56. Example #2 Factors lazy mode for Supplier set to true (default) Fetch mode used for querying on Product is Select fetch mode (default) Supplier information is accessed Caching play a role the Supplier is accessed the second time Sample project in the hands-on lab HibernateHQLQuery-LazyTrue-SelectFetch- SupplierAccessed-Caching 56
  • 57. Access Supplier Through Cache System.out.println("n---Performing HQL query with LazyTrue-SelectFetch-SupplierAccessed..." Query query = session.createQuery("from Product"); List results = query.list(); displayProductsListWithSupplierName(results); System.out.println("n---Performing HQL query using Cache..."); Query query = session.createQuery("from Product"); List results = query.list(); displayProductsListWithSupplierName(results); // Clear cache session.clear(); System.out.println("n---Performing HQL query after clearing Cache..."); Query query = session.createQuery("from Product"); List results = query.list(); displayProductsListWithSupplierName(results); 57
  • 58. Select Statements Used select ... various field names ... from PRODUCT select ... various field names ... from SUPPLIER where SUPPLIER.id=? select ... various field names ... from SUPPLIER where SUPPLIER.id=? select ... various field names ... from SUPPLIER where SUPPLIER.id=? select ... various field names ... from PRODUCT select ... various field names ... from PRODUCT select ... various field names ... from SUPPLIER where SUPPLIER.id=? select ... various field names ... from SUPPLIER where SUPPLIER.id=? select ... various field names ... from SUPPLIER where SUPPLIER.id=? 58
  • 60. Recommendation Join fetching is good for small collection of child objects often used with parent Large collections and/or not always used collections are better retrieved with lazy select fetching 60
  • 61. Hibernate Fetch Strategies, N+1 Select Problem 61