Hibernate - reduce the number of requests

A product may have 1 or more daughter products that form a tree structure. The baby product will also refer to the parent Prdoduct. In my test code, I created 1 parent ( mortgage) with 2 children ( ml and me). Why am I trying to load the parent Product entity = (Product) hibernateTemplate.get(Product.class, mortgage.getId());, it uses the connection correctly.

  • However, hibernation is also trying to load child elements ml and me , although both of them have no children . Is there a way to avoid this so that I can reduce the number of requests from 3 to 1.

  • Generated SQL uses dynamically generated aliases such as children0_. Is there any way hibernate can use a custom alias name say 'p'

Here is my hbm and test code respectively.

HBM

<class name="Product" table="PRODUCT">
        <id name="id" type="java.lang.Long" column="ID">
            <generator class="native">
                <param name="sequence">PRODUCT_SN</param>
            </generator>
        </id>

        <many-to-one name="parent" class="Product" lazy="false" column="PARENT" />

        <set name="children" lazy="false" fetch="join"  table="PRODUCT" cascade="all">
            <key>
                <column name="PARENT" />
            </key>
            <one-to-many class="Product" />
        </set>
        <property name="code" type="java.lang.String" column="CODE" not-null="true" />
        <property name="name" type="java.lang.String" column="NAME" />
        <property name="startDate" type="java.util.Date" column="STARTDATE" />
        <property name="endDate" type="java.util.Date" column="ENDDATE" />
        <property name="decisionable" type="boolean" column="ISDECISIONABLE" />
        <property name="selectable" type="boolean" column="ISSELECTABLE" />
    </class>

Test

public class ProductTest extends HibernateTestCase
{
    @Test
    public void save()
    {
        // Level 1 - mortgage LOB
        Product mortgage = new Product();
        mortgage.setCode("Mortgage");

        Product ml = new Product();
        ml.setCode("Mortgage Loan");

        Product me = new Product();
        me.setCode("Home Equity LOC");

        mortgage.addChild(ml);
        mortgage.addChild(me);

        hibernateTemplate.save(mortgage);
        Product entity = (Product) hibernateTemplate.get(Product.class, mortgage.getId());
    }       
}

LOG

Hibernate: select product0_.ID as ID0_1_, product0_.PARENT as PARENT0_1_, product0_.CODE as CODE0_1_, product0_.NAME as NAME0_1_, product0_.STARTDATE as STARTDATE0_1_, product0_.ENDDATE as ENDDATE0_1_, product0_.ISDECISIONABLE as ISDECISI7_0_1_, product0_.ISSELECTABLE as ISSELECT8_0_1_, children1_.PARENT as PARENT3_, children1_.ID as ID3_, children1_.ID as ID0_0_, children1_.PARENT as PARENT0_0_, children1_.CODE as CODE0_0_, children1_.NAME as NAME0_0_, children1_.STARTDATE as STARTDATE0_0_, children1_.ENDDATE as ENDDATE0_0_, children1_.ISDECISIONABLE as ISDECISI7_0_0_, children1_.ISSELECTABLE as ISSELECT8_0_0_ from PRODUCT product0_ left outer join PRODUCT children1_ on product0_.ID=children1_.PARENT where product0_.ID=?
DEBUG [org.hibernate.type.LongType] binding '1' to parameter: 1

DEBUG [org.hibernate.type.LongType] returning '2' as column: ID0_0_
DEBUG [org.hibernate.type.LongType] returning '1' as column: PARENT0_0_
DEBUG [org.hibernate.type.StringType] returning 'Mortgage Loan' as column: CODE0_0_
DEBUG [org.hibernate.type.StringType] returning null as column: NAME0_0_
DEBUG [org.hibernate.type.TimestampType] returning null as column: STARTDATE0_0_
DEBUG [org.hibernate.type.TimestampType] returning null as column: ENDDATE0_0_
DEBUG [org.hibernate.type.BooleanType] returning 'false' as column: ISDECISI7_0_0_
DEBUG [org.hibernate.type.BooleanType] returning 'false' as column: ISSELECT8_0_0_

DEBUG [org.hibernate.type.LongType] returning null as column: PARENT0_1_
DEBUG [org.hibernate.type.StringType] returning 'Mortgage' as column: CODE0_1_
DEBUG [org.hibernate.type.StringType] returning null as column: NAME0_1_
DEBUG [org.hibernate.type.TimestampType] returning null as column: STARTDATE0_1_
DEBUG [org.hibernate.type.TimestampType] returning null as column: ENDDATE0_1_
DEBUG [org.hibernate.type.BooleanType] returning 'false' as column: ISDECISI7_0_1_
DEBUG [org.hibernate.type.BooleanType] returning 'false' as column: ISSELECT8_0_1_

DEBUG [org.hibernate.type.LongType] returning '1' as column: PARENT3_
DEBUG [org.hibernate.type.LongType] returning '2' as column: ID3_
DEBUG [org.hibernate.type.LongType] returning '3' as column: ID0_0_
DEBUG [org.hibernate.type.LongType] returning '1' as column: PARENT0_0_
DEBUG [org.hibernate.type.StringType] returning 'Home Equity LOC' as column: CODE0_0_
DEBUG [org.hibernate.type.StringType] returning null as column: NAME0_0_
DEBUG [org.hibernate.type.TimestampType] returning null as column: STARTDATE0_0_
DEBUG [org.hibernate.type.TimestampType] returning null as column: ENDDATE0_0_
DEBUG [org.hibernate.type.BooleanType] returning 'false' as column: ISDECISI7_0_0_
DEBUG [org.hibernate.type.BooleanType] returning 'false' as column: ISSELECT8_0_0_
DEBUG [org.hibernate.type.LongType] returning '1' as column: PARENT3_
DEBUG [org.hibernate.type.LongType] returning '3' as column: ID3_

Hibernate: select children0_.PARENT as PARENT1_, children0_.ID as ID1_, children0_.ID as ID0_0_, children0_.PARENT as PARENT0_0_, children0_.CODE as CODE0_0_, children0_.NAME as NAME0_0_, children0_.STARTDATE as STARTDATE0_0_, children0_.ENDDATE as ENDDATE0_0_, children0_.ISDECISIONABLE as ISDECISI7_0_0_, children0_.ISSELECTABLE as ISSELECT8_0_0_ from PRODUCT children0_ where children0_.PARENT=?
DEBUG [org.hibernate.type.LongType] binding '3' to parameter: 1

Hibernate: select children0_.PARENT as PARENT1_, children0_.ID as ID1_, children0_.ID as ID0_0_, children0_.PARENT as PARENT0_0_, children0_.CODE as CODE0_0_, children0_.NAME as NAME0_0_, children0_.STARTDATE as STARTDATE0_0_, children0_.ENDDATE as ENDDATE0_0_, children0_.ISDECISIONABLE as ISDECISI7_0_0_, children0_.ISSELECTABLE as ISSELECT8_0_0_ from PRODUCT children0_ where children0_.PARENT=?
DEBUG [org.hibernate.type.LongType] binding '2' to parameter: 1
+3
source share
2 answers

You should probably mark the attitude as lazy so that children only load when necessary. If you want to load node with your children, use the highlighted query:

select p from Product left join fetch p.children where p.id = :id
+3
source

I think the reason you see everything childrenis because you have something fetch="join"defined in yours <set name="children">. If you remove this, I believe that Hibernate will pull only Product.

+1
source

Source: https://habr.com/ru/post/1794485/


All Articles