-->
These old forums are deprecated now and set to read-only. We are waiting for you on our new forums!
More modern, Discourse-based and with GitHub/Google/Twitter authentication built-in.

All times are UTC - 5 hours [ DST ]



Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 1 post ] 
Author Message
 Post subject: Hibernate unable to lazy load when FK joins to a component?
PostPosted: Wed Jun 01, 2005 10:30 pm 
Newbie

Joined: Tue Jul 20, 2004 8:52 pm
Posts: 6
My problem is that I have a many-to-one association that is has a multi-column foreign key that is mapped to a component in the joining class. This association always seems to be eagerly loaded in a seperate select. It is killing the performance of some of the common reports that need to be generated, as a query returning a hundreds of these objects requires hundreds more queries to uneccassarily load the association.

If I have another many-to-one association to Bar (lazyBar in my example), but use a single column joining to the primary key, it shows that it can be proxied/lazy loaded.

The association Foo.bar is mapped with update=false and insert=false, I just want it there for easy traversal of the object graph. (in my real object model, the columns equivalent to uk1 and uk2 are owned/updated by other many-to-one associations)

If you would like a zip of an basic eclipse project with this code, then email me at dcampagnoli ~at~ nd.edu.au

Hibernate version:
3.0.5

Mapping documents:
Code:
<?xml version="1.0"?>

<!DOCTYPE hibernate-mapping PUBLIC
    "-//Hibernate/Hibernate Mapping DTD 2.0//EN"
    "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">

<hibernate-mapping>
    <class
        name="test.Foo"
        table="FOO"
        dynamic-update="false"
        dynamic-insert="false"
        lazy="true"
    >

        <id
            name="id"
            column="id"
            type="java.lang.Long"
        >
            <generator class="increment">
            </generator>
        </id>
       
        <many-to-one
            name="bar"
            class="test.Bar"
            cascade="none"
            fetch="select"
            update="false"
            insert="false"
            access="property"
            property-ref="uk"
        >
            <column name="fk1" />
            <column name="fk2" />
        </many-to-one>
       
       
        <many-to-one
            name="lazyBar"
            class="test.Bar"
            cascade="none"
            fetch="select"
            update="true"
            insert="true"
            access="property"
        >
            <column name="lazyBar" />
        </many-to-one>
       
       

        <property
            name="fk1"
            type="java.lang.Long"
            update="true"
            insert="true"
            access="property"
            column="fk1"
        />
        <property
            name="fk2"
            type="java.lang.Long"
            update="true"
            insert="true"
            access="property"
            column="fk2"
        />

    </class>

</hibernate-mapping>


Code:
<?xml version="1.0"?>

<!DOCTYPE hibernate-mapping PUBLIC
    "-//Hibernate/Hibernate Mapping DTD 2.0//EN"
    "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">

<hibernate-mapping>
    <class
        name="test.Bar"
        table="BAR"
        dynamic-update="false"
        dynamic-insert="false"
        lazy="true"
    >
        <id
            name="id"
            column="id"
            type="java.lang.Long"
        >
            <generator class="increment">
            </generator>
        </id>
       
        <component
            name="uk"
            class="test.UK"
            access="property"
            insert="false"
            update="false"
            unique="true"
        >

            <property
                name="uk1"
                type="java.lang.Long"
                update="false"
                insert="false"
                access="property"
                column="uk1"
            />
            <property
                name="uk2"
                type="java.lang.Long"
                update="false"
                insert="false"
                access="property"
                column="uk2"
            />
        </component>

        <property
            name="uk1"
            type="java.lang.Long"
            update="true"
            insert="true"
            access="property"
            column="uk1"
        />

        <property
            name="uk2"
            type="java.lang.Long"
            update="true"
            insert="true"
            access="property"
            column="uk2"
        />

    </class>

</hibernate-mapping>


Code between sessionFactory.openSession() and session.close():
Code:
// save two bars. the first will be used for the component mapped association
      Bar bar = new Bar();
      bar.setUk1(new Long(1));
      bar.setUk2(new Long(2));
      session.save(bar);
     
      Bar lazyBar = new Bar();
      lazyBar.setUk1(new Long(3));
      lazyBar.setUk2(new Long(4));
      session.save(lazyBar);
     
      // save two foo's. The uk's (1, 2) match that of bar
      session.save(new Foo(1, 2, bar, lazyBar));
      session.save(new Foo(1, 2, bar, lazyBar));
     
      session.flush();
      session.close();
      System.out.println();
     
      session = factory.openSession();
     
      System.out.println("Quering...");
     
      List foos = session.createQuery("from Foo f").list();
     
      System.out.println("Found " + foos.size());
     
      Foo foo = (Foo) foos.iterator().next();
      System.out.println("retrieving bar");
      System.out.println(foo.getBar());
      System.out.println("retrieving lazyBar");
      System.out.println(foo.getLazyBar());


Full stack trace of any exception that occurs:
N/A

Name and version of the database you are using:
Problem found with SQL Server. Test case done with HSQL

The generated SQL (show_sql=true): (includes my System.out calls)
Hibernate: insert into BAR (uk1, uk2, id) values (?, ?, ?)
Hibernate: insert into BAR (uk1, uk2, id) values (?, ?, ?)
Hibernate: insert into FOO (lazyBar, fk1, fk2, id) values (?, ?, ?, ?)
Hibernate: insert into FOO (lazyBar, fk1, fk2, id) values (?, ?, ?, ?)

Quering...
Hibernate: select foo0_.id as id, foo0_.fk1 as fk2_0_, foo0_.fk2 as fk3_0_, foo0_.lazyBar as lazyBar0_ from FOO foo0_
Hibernate: select bar0_.id as id0_, bar0_.uk1 as uk2_1_0_, bar0_.uk2 as uk3_1_0_ from BAR bar0_ where bar0_.uk1=? and bar0_.uk2=?
Hibernate: select bar0_.id as id0_, bar0_.uk1 as uk2_1_0_, bar0_.uk2 as uk3_1_0_ from BAR bar0_ where bar0_.uk1=? and bar0_.uk2=?
Found 2
retrieving bar
test.Bar@16be68f
retrieving lazyBar
Hibernate: select bar0_.id as id0_, bar0_.uk1 as uk2_1_0_, bar0_.uk2 as uk3_1_0_ from BAR bar0_ where bar0_.id=?
test.Bar@126f827


Debug level Hibernate log excerpt:

09:16:04,375 DEBUG [SQL] select foo0_.id as id, foo0_.fk1 as fk2_0_, foo0_.fk2 as fk3_0_, foo0_.lazyBar as lazyBar0_ from FOO foo0_
Hibernate: select foo0_.id as id, foo0_.fk1 as fk2_0_, foo0_.fk2 as fk3_0_, foo0_.lazyBar as lazyBar0_ from FOO foo0_
09:16:04,375 DEBUG [AbstractBatcher] preparing statement
09:16:04,375 DEBUG [AbstractBatcher] about to open ResultSet (open ResultSets: 0, globally: 0)
09:16:04,375 DEBUG [Loader] processing result set
09:16:04,375 DEBUG [Loader] result set row: 0
09:16:04,375 DEBUG [LongType] returning '1' as column: id
09:16:04,375 DEBUG [Loader] result row: EntityKey[test.Foo#1]
09:16:04,375 DEBUG [Loader] Initializing object from ResultSet: [test.Foo#1]
09:16:04,375 DEBUG [BasicEntityPersister] Hydrating entity: [test.Foo#1]
09:16:04,375 DEBUG [LongType] returning '1' as column: fk2_0_
09:16:04,375 DEBUG [LongType] returning '2' as column: fk3_0_
09:16:04,375 DEBUG [LongType] returning '2' as column: lazyBar0_
09:16:04,375 DEBUG [LongType] returning '1' as column: fk2_0_
09:16:04,375 DEBUG [LongType] returning '2' as column: fk3_0_
09:16:04,375 DEBUG [Loader] result set row: 1
09:16:04,375 DEBUG [LongType] returning '2' as column: id
09:16:04,375 DEBUG [Loader] result row: EntityKey[test.Foo#2]
09:16:04,375 DEBUG [Loader] Initializing object from ResultSet: [test.Foo#2]
09:16:04,375 DEBUG [BasicEntityPersister] Hydrating entity: [test.Foo#2]
09:16:04,375 DEBUG [LongType] returning '1' as column: fk2_0_
09:16:04,375 DEBUG [LongType] returning '2' as column: fk3_0_
09:16:04,375 DEBUG [LongType] returning '2' as column: lazyBar0_
09:16:04,375 DEBUG [LongType] returning '1' as column: fk2_0_
09:16:04,375 DEBUG [LongType] returning '2' as column: fk3_0_
09:16:04,375 DEBUG [Loader] done processing result set (2 rows)
09:16:04,375 DEBUG [AbstractBatcher] about to close ResultSet (open ResultSets: 1, globally: 1)
09:16:04,375 DEBUG [AbstractBatcher] about to close PreparedStatement (open PreparedStatements: 1, globally: 1)
09:16:04,375 DEBUG [AbstractBatcher] closing statement
09:16:04,375 DEBUG [Loader] total objects hydrated: 2
09:16:04,375 DEBUG [TwoPhaseLoad] resolving associations for [test.Foo#1]
09:16:04,390 DEBUG [Loader] loading entity: [test.Bar#component[uk1,uk2]{uk2=2, uk1=1}]
09:16:04,390 DEBUG [AbstractBatcher] about to open PreparedStatement (open PreparedStatements: 0, globally: 0)
09:16:04,390 DEBUG [SQL] select bar0_.id as id0_, bar0_.uk1 as uk2_1_0_, bar0_.uk2 as uk3_1_0_ from BAR bar0_ where bar0_.uk1=? and bar0_.uk2=?
Hibernate: select bar0_.id as id0_, bar0_.uk1 as uk2_1_0_, bar0_.uk2 as uk3_1_0_ from BAR bar0_ where bar0_.uk1=? and bar0_.uk2=?
09:16:04,390 DEBUG [AbstractBatcher] preparing statement
09:16:04,390 DEBUG [LongType] binding '1' to parameter: 1
09:16:04,390 DEBUG [LongType] binding '2' to parameter: 2
09:16:04,390 DEBUG [AbstractBatcher] about to open ResultSet (open ResultSets: 0, globally: 0)
09:16:04,390 DEBUG [Loader] processing result set
09:16:04,390 DEBUG [Loader] result set row: 0
09:16:04,390 DEBUG [LongType] returning '1' as column: id0_
09:16:04,390 DEBUG [Loader] result row: EntityKey[test.Bar#1]
09:16:04,390 DEBUG [Loader] Initializing object from ResultSet: [test.Bar#1]
09:16:04,390 DEBUG [BasicEntityPersister] Hydrating entity: [test.Bar#1]
09:16:04,390 DEBUG [LongType] returning '1' as column: uk2_1_0_
09:16:04,390 DEBUG [LongType] returning '2' as column: uk3_1_0_
09:16:04,390 DEBUG [LongType] returning '1' as column: uk2_1_0_
09:16:04,390 DEBUG [LongType] returning '2' as column: uk3_1_0_
09:16:04,390 DEBUG [Loader] done processing result set (1 rows)
09:16:04,390 DEBUG [AbstractBatcher] about to close ResultSet (open ResultSets: 1, globally: 1)
09:16:04,390 DEBUG [AbstractBatcher] about to close PreparedStatement (open PreparedStatements: 1, globally: 1)
09:16:04,390 DEBUG [AbstractBatcher] closing statement
09:16:04,390 DEBUG [Loader] total objects hydrated: 1
09:16:04,390 DEBUG [TwoPhaseLoad] resolving associations for [test.Bar#1]
09:16:04,390 DEBUG [TwoPhaseLoad] done materializing entity [test.Bar#1]
09:16:04,390 DEBUG [Loader] done entity load
09:16:04,390 DEBUG [DefaultLoadEventListener] loading entity: [test.Bar#2]
09:16:04,390 DEBUG [DefaultLoadEventListener] creating new proxy for entity
09:16:04,390 DEBUG [TwoPhaseLoad] done materializing entity [test.Foo#1]
09:16:04,390 DEBUG [TwoPhaseLoad] resolving associations for [test.Foo#2]
09:16:04,390 DEBUG [Loader] loading entity: [test.Bar#component[uk1,uk2]{uk2=2, uk1=1}]
09:16:04,390 DEBUG [AbstractBatcher] about to open PreparedStatement (open PreparedStatements: 0, globally: 0)
09:16:04,390 DEBUG [SQL] select bar0_.id as id0_, bar0_.uk1 as uk2_1_0_, bar0_.uk2 as uk3_1_0_ from BAR bar0_ where bar0_.uk1=? and bar0_.uk2=?
Hibernate: select bar0_.id as id0_, bar0_.uk1 as uk2_1_0_, bar0_.uk2 as uk3_1_0_ from BAR bar0_ where bar0_.uk1=? and bar0_.uk2=?
09:16:04,390 DEBUG [AbstractBatcher] preparing statement
09:16:04,390 DEBUG [LongType] binding '1' to parameter: 1
09:16:04,390 DEBUG [LongType] binding '2' to parameter: 2
09:16:04,390 DEBUG [AbstractBatcher] about to open ResultSet (open ResultSets: 0, globally: 0)
09:16:04,390 DEBUG [Loader] processing result set
09:16:04,390 DEBUG [Loader] result set row: 0
09:16:04,390 DEBUG [LongType] returning '1' as column: id0_
09:16:04,406 DEBUG [Loader] result row: EntityKey[test.Bar#1]
09:16:04,406 DEBUG [Loader] done processing result set (1 rows)
09:16:04,406 DEBUG [AbstractBatcher] about to close ResultSet (open ResultSets: 1, globally: 1)
09:16:04,406 DEBUG [AbstractBatcher] about to close PreparedStatement (open PreparedStatements: 1, globally: 1)
09:16:04,406 DEBUG [AbstractBatcher] closing statement
09:16:04,406 DEBUG [Loader] total objects hydrated: 0
09:16:04,406 DEBUG [Loader] done entity load
09:16:04,406 DEBUG [DefaultLoadEventListener] loading entity: [test.Bar#2]
09:16:04,406 DEBUG [DefaultLoadEventListener] entity proxy found in session cache
09:16:04,406 DEBUG [TwoPhaseLoad] done materializing entity [test.Foo#2]
09:16:04,406 DEBUG [PersistenceContext] initializing non-lazy collections
09:16:04,406 DEBUG [JDBCContext] after autocommit
Found 2


Top
 Profile  
 
Display posts from previous:  Sort by  
Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 1 post ] 

All times are UTC - 5 hours [ DST ]


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum

Search for:
© Copyright 2014, Red Hat Inc. All rights reserved. JBoss and Hibernate are registered trademarks and servicemarks of Red Hat, Inc.