-->
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.  [ 5 posts ] 
Author Message
 Post subject: @LazyCollection(LazyCollectionOption.EXTRA) Problem
PostPosted: Wed May 10, 2006 10:05 am 
Newbie

Joined: Wed May 10, 2006 9:09 am
Posts: 13
Hello,

I am new to Hibernate and this is my first post in this forum, so please forgive me if my question is silly.

I am using SVN revision 9921 of hibernate-annotations and hibernate 3.2 beta.

I have two Entity classes. Account is a tree structure and Journal is a table structure:

Code:
public class Account {

    @ManyToOne(targetEntity=Account.class)
    private Account parent;

    @OneToMany(mappedBy="parent", targetEntity=Account.class)
    @Cascade({CascadeType.DELETE})
    private List<Account> children = new ArrayList<Account>();

    @OneToMany(mappedBy="account", targetEntity=Journal.class)
    @LazyCollection(LazyCollectionOption.EXTRA)     
    @BatchSize(size=20)
    private List<Journal> journals = new ArrayList<Journal>();   

}

public class Journal {

    @ManyToOne(targetEntity=Account.class)
    private Account account;

}


I want to make journals an Extra-Lazy collection.

Getting journals.size() issues a "select count(id)..." query so it seems fine.

But when I access a journal (like journals.get(0) ) all the journals are read from the database and no more queries issued for subsequent access of journals.

Any guidance will be more than welcome.
Thanks in advance.

Ecmel Ercan


Top
 Profile  
 
 Post subject: More Detailed Test Case
PostPosted: Thu May 11, 2006 12:25 am 
Newbie

Joined: Wed May 10, 2006 9:09 am
Posts: 13
Parent class:

Code:
@Entity
public class TestParent implements Serializable {
   
    @Id @GeneratedValue                 
    private Long id;
   
    @OneToMany(mappedBy="parent", targetEntity=TestChild.class)
    @LazyCollection(LazyCollectionOption.EXTRA)     
    private List<TestChild> children = new ArrayList<TestChild>();   

    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public List<TestChild> getChildren() {
        return children;
    }

    public void setChildren(List<TestChild> children) {
        this.children = children;
    }
   
}


Child class:

Code:
@Entity
public class TestChild implements Serializable {
   
    @Id @GeneratedValue                 
    private Long id;
   
    @ManyToOne(targetEntity=TestParent.class)
    private TestParent parent;

    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public TestParent getParent() {
        return parent;
    }

    public void setParent(TestParent parent) {
        this.parent = parent;
    }
   
}


The schema:

Code:
CREATE MEMORY TABLE TESTPARENT(
ID BIGINT GENERATED BY DEFAULT AS IDENTITY(START WITH 1) NOT NULL PRIMARY KEY
)

CREATE MEMORY TABLE TESTCHILD(
ID BIGINT GENERATED BY DEFAULT AS IDENTITY(START WITH 1) NOT NULL PRIMARY KEY,
PARENT_ID BIGINT
)

ALTER TABLE TESTCHILD ADD CONSTRAINT FK2F8AEB8A499EB72D FOREIGN KEY(PARENT_ID) REFERENCES TESTPARENT(ID)


The data:

Code:
INSERT INTO TESTPARENT VALUES(1)
INSERT INTO TESTPARENT VALUES(2)
INSERT INTO TESTCHILD VALUES(1,1)
INSERT INTO TESTCHILD VALUES(2,1)
INSERT INTO TESTCHILD VALUES(3,1)
INSERT INTO TESTCHILD VALUES(4,1)
INSERT INTO TESTCHILD VALUES(5,1)
INSERT INTO TESTCHILD VALUES(6,1)
INSERT INTO TESTCHILD VALUES(7,1)
INSERT INTO TESTCHILD VALUES(8,1)
INSERT INTO TESTCHILD VALUES(9,1)
INSERT INTO TESTCHILD VALUES(10,1)
INSERT INTO TESTCHILD VALUES(11,2)
INSERT INTO TESTCHILD VALUES(12,2)
INSERT INTO TESTCHILD VALUES(13,2)
INSERT INTO TESTCHILD VALUES(14,2)
INSERT INTO TESTCHILD VALUES(15,2)
INSERT INTO TESTCHILD VALUES(16,2)
INSERT INTO TESTCHILD VALUES(17,2)
INSERT INTO TESTCHILD VALUES(18,2)
INSERT INTO TESTCHILD VALUES(19,2)


The code:

Code:
transaction = session.beginTransaction();
List parents = session.createQuery("from TestParent").list();           
transaction.commit();

TestParent parent = (TestParent) parents.get(0);
System.out.println(parent.getChildren().size());
           
for (TestChild child : parent.getChildren()) {
    System.out.println(child.getId());           
}


Generated queries for the above code:

Code:

For getChildren().size():

select count(id) from TestChild where parent_id =?

For child.getId():

select children0_.parent_id as parent2_1_, children0_.id as id1_, children0_.id as id5_0_, children0_.parent_id as parent2_5_0_ from TestChild children0_ where children0_.parent_id=?



The last query is generated only once for the entire loop so the entire collection is loaded into memory on first child access.


Top
 Profile  
 
 Post subject: hbm mappings
PostPosted: Thu May 11, 2006 3:15 am 
Newbie

Joined: Wed May 10, 2006 9:09 am
Posts: 13
I tried to map the classes through xml Hibernate mappings instead of annotations, the result is the same.

TestParent.hbm.xml

Code:
<hibernate-mapping>

    <class name="TestParent" table="TESTPARENT">
        <id name="id" column="ID">
            <generator class="native"/>
        </id>

        <list name="children" lazy="extra">
            <key column="PARENT_ID" />
            <list-index column="id" base="1"/>
            <one-to-many class="TestChild" />
        </list>
               
    </class>
   
</hibernate-mapping>


TestChild.hbm.xml

Code:
<hibernate-mapping>

    <class name="TestChild" table="TESTCHILD">
        <id name="id" column="ID">
            <generator class="native"/>
        </id>
               
        <many-to-one name="parent" column="id" class="TestParent" />       
   
    </class>
 
</hibernate-mapping>


Top
 Profile  
 
 Post subject: Partial success
PostPosted: Thu May 11, 2006 6:34 pm 
Newbie

Joined: Wed May 10, 2006 9:09 am
Posts: 13
Instead of for loop:

Code:
System.out.println(parent.getChildren().size());
System.out.println(parent.getChildren().get(0).getId());   
System.out.println(parent.getChildren().get(1).getId());


This works using hbm.xml files above but not work with annotations.


Top
 Profile  
 
 Post subject:
PostPosted: Tue May 23, 2006 1:20 pm 
Hibernate Team
Hibernate Team

Joined: Sun Sep 14, 2003 3:54 am
Posts: 7256
Location: Paris, France
There is no way to lazy extra a get on a bag collection.
Check the annotations reference documentation on how to use a non bag collection.

_________________
Emmanuel


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

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.