Hibernate version: 3.0
Mapping documents:
Code:
<class name="A" table="A" lazy="true">
<id name="id" column="ID" unsaved-value="null" />
<set name="bs" inverse="true" lazy="true" cascade="all-delete-orphan">
<key column="A_ID" on-delete="cascade" />
<one-to-many class="B" />
</set>
</class>
<class name="B" table="B" lazy="true">
<id name="id" column="ID" unsaved-value="null" />
<property name="foo" column="FOO" />
<many-to-one name="a" class="A" column="A_ID" lazy="false" not-null="true" />
</class>
Code between sessionFactory.openSession() and session.close():Code:
return session.createCriteria(A.class).
setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY).
setFetchMode("bs", FetchMode.JOIN).
createCriteria("bs").
add(Restrictions.lt("foo", new Integer(50))).list();
Full stack trace of exception that occurs when trying to execute the following code:Code:
List l = dao.getAs1();
for (Iterator i = l.iterator(); i.hasNext();) {
A a = (A) i.next();
System.err.println("Record ID #" + a.getId() + " has " + a.getBs().size() + " B's");
}
Code:
org.hibernate.LazyInitializationException: failed to lazily initialize a collection of role: com.kraft.ops.trans.qtts.detention.model.A.bs -
no session or session was closed
at org.hibernate.collection.AbstractPersistentCollection.throwLazyInitializationException(AbstractPersistentCollection.java:191)
at org.hibernate.collection.AbstractPersistentCollection.initialize(AbstractPersistentCollection.java:183)
at org.hibernate.collection.AbstractPersistentCollection.read(AbstractPersistentCollection.java:48)
at org.hibernate.collection.PersistentSet.size(PersistentSet.java:110)
at com.kraft.ops.trans.qtts.detention.dao.hibernate.Test.main(Test.java:47)
Name and version of the database you are using:Oracle 8.1.7
Code:
CREATE TABLE A (
ID NUMBER NOT NULL,
CONSTRAINT PK_A
PRIMARY KEY ( ID ) ) ;
CREATE TABLE B (
ID NUMBER NOT NULL,
A_ID NUMBER NOT NULL,
FOO NUMBER,
CONSTRAINT PK_B
PRIMARY KEY ( ID ) ) ;
ALTER TABLE B ADD CONSTRAINT FK_B_A
FOREIGN KEY (A_ID)
REFERENCES TSTEST.A (ID) ON DELETE CASCADE;
INSERT INTO A VALUES (1);
INSERT INTO A VALUES (2);
INSERT INTO B VALUES (1, 1, 10);
INSERT INTO B VALUES (2, 1, 20);
INSERT INTO B VALUES (3, 2, 100);
INSERT INTO B VALUES (4, 2, 15);
The generated SQL (show_sql=true):Code:
select this_.ID as ID1_, b1_.ID as ID0_, b1_.FOO as FOO7_0_, b1_.A_ID as A3_7_0_
from tstest.A this_, tstest.B b1_ where this_.ID=b1
_.A_ID and b1_.FOO<?
Basically, I have class A which holds a collection of B. The collection is loaded lazy by default, since it's not needed often. I want to retrieve a list of A's (with collections of B's initialized), based on restrictions placed on B's. I've tried different approaches, with FetchMode.EAGER (as recommended by HiA) or with FetchMode.JOIN - either one gets me a LazyInitializationException when I try to access B's collection. ANything I'm doing wrong here?