SlideShare uma empresa Scribd logo
1 de 61
Baixar para ler offline
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

Mais conteúdo relacionado

Semelhante a Hibernatejoinfetch

Grails EE
Grails EEGrails EE
Grails EEGR8Conf
 
QA Meetup at Signavio (Berlin, 06.06.19)
QA Meetup at Signavio (Berlin, 06.06.19)QA Meetup at Signavio (Berlin, 06.06.19)
QA Meetup at Signavio (Berlin, 06.06.19)Anesthezia
 
Tests and Testability: Apex Structure and Strategy
Tests and Testability: Apex Structure and StrategyTests and Testability: Apex Structure and Strategy
Tests and Testability: Apex Structure and StrategySalesforce Developers
 
07 Retrieving Objects
07 Retrieving Objects07 Retrieving Objects
07 Retrieving ObjectsRanjan Kumar
 
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 - FundamentalsSumo Logic
 
L14: Access Rights and Triggers
L14: Access Rights and TriggersL14: Access Rights and Triggers
L14: Access Rights and Triggersmedialeg gmbh
 
Big Data Analytics using Mahout
Big Data Analytics using MahoutBig Data Analytics using Mahout
Big Data Analytics using MahoutIMC 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 tutorialslenorajohnson
 
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 demoHridyesh Bisht
 
Building a Pyramid: Symfony Testing Strategies
Building a Pyramid: Symfony Testing StrategiesBuilding a Pyramid: Symfony Testing Strategies
Building a Pyramid: Symfony Testing StrategiesCiaranMcNulty
 
Extending MariaDB with user-defined functions
Extending MariaDB with user-defined functionsExtending MariaDB with user-defined functions
Extending MariaDB with user-defined functionsMariaDB plc
 
Apache Calcite Tutorial - BOSS 21
Apache Calcite Tutorial - BOSS 21Apache Calcite Tutorial - BOSS 21
Apache Calcite Tutorial - BOSS 21Stamatis Zampetakis
 
2006 - Basta!: Advanced server controls
2006 - Basta!: Advanced server controls2006 - Basta!: Advanced server controls
2006 - Basta!: Advanced server controlsDaniel 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 181Mahmoud 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 Developerscboecking
 
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
 
Most Advanced GTM Deployment. Ever!
Most Advanced GTM Deployment. Ever!Most Advanced GTM Deployment. Ever!
Most Advanced GTM Deployment. Ever!Phil Pearce
 

Semelhante a Hibernatejoinfetch (20)

Grails EE
Grails EEGrails EE
Grails EE
 
QA Meetup at Signavio (Berlin, 06.06.19)
QA Meetup at Signavio (Berlin, 06.06.19)QA Meetup at Signavio (Berlin, 06.06.19)
QA Meetup at Signavio (Berlin, 06.06.19)
 
Tests and Testability: Apex Structure and Strategy
Tests and Testability: Apex Structure and StrategyTests and Testability: Apex Structure and Strategy
Tests and Testability: Apex Structure and Strategy
 
07 Retrieving Objects
07 Retrieving Objects07 Retrieving Objects
07 Retrieving Objects
 
Software slide
Software slideSoftware slide
Software slide
 
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
 
L14: Access Rights and Triggers
L14: Access Rights and TriggersL14: Access Rights and Triggers
L14: Access Rights and Triggers
 
Big Data Analytics using Mahout
Big Data Analytics using MahoutBig Data Analytics using Mahout
Big Data Analytics using Mahout
 
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
 
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
 
Building a Pyramid: Symfony Testing Strategies
Building a Pyramid: Symfony Testing StrategiesBuilding a Pyramid: Symfony Testing Strategies
Building a Pyramid: Symfony Testing Strategies
 
Extending MariaDB with user-defined functions
Extending MariaDB with user-defined functionsExtending MariaDB with user-defined functions
Extending MariaDB with user-defined functions
 
Apache Calcite Tutorial - BOSS 21
Apache Calcite Tutorial - BOSS 21Apache Calcite Tutorial - BOSS 21
Apache Calcite Tutorial - BOSS 21
 
2006 - Basta!: Advanced server controls
2006 - Basta!: Advanced server controls2006 - Basta!: Advanced server controls
2006 - Basta!: Advanced server controls
 
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
 
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
 
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)
 
Testing Spring Applications
Testing Spring ApplicationsTesting Spring Applications
Testing Spring Applications
 
Most Advanced GTM Deployment. Ever!
Most Advanced GTM Deployment. Ever!Most Advanced GTM Deployment. Ever!
Most Advanced GTM Deployment. Ever!
 

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