[
http://opensource.atlassian.com/projects/hibernate/browse/HHH-2299?page=c...
]
Maxim Karavaev commented on HHH-2299:
-------------------------------------
I have the similar proplem... Let's say, we have a two entity A and B with
bidirectional relation:
<class entity-name="A" table="TABLE_A">
<id column="ID" name="id" type="int"/>
<set name="Bs" table="TABLE_AB">
<key column="B_ID"/>
<many-to-many column="A_ID" entity-name="B"/>
</set>
</class>
<class entity-name="B" table="TABLE_B">
<id column="ID" name="id" type="int"/>
<set name="As" table="TABLE_AB"
inverse="true">
<key column="A_ID"/>
<many-to-many column="B_ID" entity-name="A"/>
</set>
</class>
I use hibernate in EJB environment. Method of some session bean:
...
public void addLinkA2B( Integer a_id, Integer b_id )
throws FinderException, CreateException
{
final Session session = getSession();
final Session dSession = session.getSession( EntityMode.MAP );
try
{
final Map a_instance = ( Map )dSession.get( "A", a_id );
if( a_instance == null )
{
throw new FinderException( "Add link failed for due to '" +
a_id + "' not found" );
}
final Map b_instance = ( Map )dSession.get( "B", b_id );
if( b_instance == null )
{
throw new FinderException( "Add link failed for due to '" +
b_id + "' not found" );
}
final Collection links = ( Collection )a_instance.get( "Bs" );
links.add( b_instance );
dSession.flush();
}
catch( HibernateException e1 )
{
throw new CreateException( "Add link failed due to " + e1.toString()
);
}
finally
{
session.close();
}
}
...
and now, testcase:
...
test.createA( 1 );
test.createA( 2 );
test.createB( 1 );
test.addLinkA2B( 1, 1 );
// next line throws a LazyInitializationException
test.addLinkA2B( 2, 1 );
test.createB( 2 );
test.addLinkA2B( 1, 2 );
test.addLinkA2B( 2, 2 );
...
(full source attached)
In the log file, at first invocation of addLinkA2B:
Hibernate: select a0_.ID as ID479_0_ from TABLE_A a0_ where a0_.ID=?
Hibernate: select b0_.ID as ID481_0_ from TABLE_B b0_ where b0_.ID=?
Hibernate: select bs0_.B_ID as B1_1_, bs0_.A_ID as A2_1_, b1_.ID as ID481_0_ from
TABLE_AB bs0_ left outer join TABLE_B b1_ on bs0_.A_ID=b1_.ID where bs0_.B_ID=?
Hibernate: select as0_.A_ID as A2_1_, as0_.B_ID as B1_1_, a1_.ID as ID479_0_ from
TABLE_AB as0_ left outer join TABLE_A a1_ on as0_.B_ID=a1_.ID where as0_.A_ID=?
Hibernate: insert into TABLE_AB (B_ID, A_ID) values (?, ?)
Nice. The next invocation (when set is not empty):
Hibernate: select a0_.ID as ID479_0_ from TABLE_A a0_ where a0_.ID=?
Hibernate: select b0_.ID as ID481_0_ from TABLE_B b0_ where b0_.ID=?
Hibernate: select bs0_.B_ID as B1_1_, bs0_.A_ID as A2_1_, b1_.ID as ID481_0_ from
TABLE_AB bs0_ left outer join TABLE_B b1_ on bs0_.A_ID=b1_.ID where bs0_.B_ID=?
Hibernate: select as0_.A_ID as A2_1_, as0_.B_ID as B1_1_, a1_.ID as ID479_0_ from
TABLE_AB as0_ left outer join TABLE_A a1_ on as0_.B_ID=a1_.ID where as0_.A_ID=?
Hibernate: select bs0_.B_ID as B1_1_, bs0_.A_ID as A2_1_, b1_.ID as ID481_0_ from
TABLE_AB bs0_ left outer join TABLE_B b1_ on bs0_.A_ID=b1_.ID where bs0_.B_ID=?
ERROR [org.hibernate.LazyInitializationException] illegal access to loading collection
Recursion initializing of a LAZY collections! And all this problems only in
PersistentSet.hashCode() method. I just use a "bag" instead of "set"
to avoid this problem, but this solution adds a some new ones.
So again, Why not to use a naitive JDK version of hashCode as in PersistenBag?
dynamic-map entity mode mappings with relationships rise lazy
initialization during performing query
Created: Yesterday 05:51 AM Updated:
Yesterday 06:07 AM
----------------------------------------------------------------------------------------------------------------------------------------------------------------
Key: HHH-2299
URL:
http://opensource.atlassian.com/projects/hibernate/browse/HHH-2299
Project: Hibernate3
Type: Bug
Components: core
Versions: 3.2.1
Reporter: Boleslaw Dawidowicz
Attachments: hibernate-issue.tar.gz
(copied from
http://jira.jboss.com/jira/browse/HIBERNATE-51)
(attached IntelliJ project with test case that reproduce this issue)
If I create bidirectional relationship between two dynamic-map entities, commit a
transaction and start new session, performing a query to obtain an entity raise
LazyInitializationException.
(full intellij project attached)
code and mappings:
public void testSF() throws Exception
{
sf.openSession();
Session es = sf.getCurrentSession();
Transaction tx = es.beginTransaction();
Map lolo = new HashMap();
lolo.put("userName", "lolo");
es.save("PortalUser", lolo);
Map dummy = new HashMap();
dummy.put("name", "dummy");
es.save("PortalRole", dummy);
Set roles = new HashSet();
roles.add(dummy);
lolo.put("roles",roles);
Map props = new HashMap();
props.put("theme", "pp");
props.put("signature", "alalala");
lolo.put("dynamic", props);
es.save("PortalUser", lolo);
tx.commit();
sf.openSession();
es = sf.getCurrentSession();
tx = es.beginTransaction();
Query query = es.createQuery("from PortalUser where
userName=:userName");
query.setParameter("userName", "lolo");
//LazyInitializationException on this LINE!!!
lolo = (Map)query.uniqueResult();
assertNotNull(lolo.get("roles"));
assertNotNull(lolo.get("dynamic"));
tx.commit();
}
<hibernate-mapping>
<class
entity-name="PortalUser">
<!--<cache usage="@portal.hibernate.cache.usage(a)"/>-->
<id
name="key"
column="jbp_uid"
type="java.lang.Long">
<generator class="native">
<param name="sequence">user_seq</param>
</generator>
</id>
<property
name="userName"
column="jbp_uname"
type="java.lang.String"
update="false"
insert="true"
unique="true"/>
<map
name="dynamic"
table="jbp_user_prop"
lazy="false"
sort="unsorted"
cascade="all">
<!--<cache usage="@portal.hibernate.cache.usage(a)"/>-->
<key column="jbp_uid"/>
<index
column="jbp_name"
type="java.lang.String"/>
<element
column="jbp_value"
type="java.lang.String"
not-null="false"
unique="false"/>
</map>
<!--@mappings@-->
<property
name="password"
column="jbp_password"
type="java.lang.String"
update="true"
insert="true"
unique="false"/>
<set
name="roles"
table="jbp_role_membership"
lazy="false"
inverse="false"
cascade="none"
sort="unsorted">
<!--<cache usage="@portal.hibernate.cache.usage(a)"/>-->
<key column="jbp_uid"/>
<many-to-many
entity-name="PortalRole"
column="jbp_rid"
outer-join="true"/>
</set>
</class>
<class
entity-name="PortalRole"
table="jbp_roles">
<!--<cache usage="@portal.hibernate.cache.usage(a)"/>-->
<id
name="key"
column="jbp_rid"
type="java.lang.Long">
<generator class="native">
<param name="sequence">user_seq</param>
</generator>
</id>
<property
name="name"
column="jbp_name"
type="java.lang.String"
update="false"
insert="true"
unique="true"/>
<property
name="displayName"
column="jbp_displayname"
type="java.lang.String"
update="true"
insert="true"
unique="true"/>
<set
name="users"
table="jbp_role_membership"
lazy="true"
inverse="true"
cascade="none"
sort="unsorted">
<!--<cache usage="@portal.hibernate.cache.usage(a)"/>-->
<key column="jbp_rid"/>
<many-to-many
entity-name="PortalUser"
column="jbp_uid"
outer-join="false"/>
</set>
</class>
</hibernate-mapping>
Stack trace:
org.hibernate.LazyInitializationException: illegal access to loading collection
at
org.hibernate.collection.AbstractPersistentCollection.initialize(AbstractPersistentCollection.java:341)
at
org.hibernate.collection.AbstractPersistentCollection.read(AbstractPersistentCollection.java:86)
at org.hibernate.collection.PersistentSet.hashCode(PersistentSet.java:411)
at java.util.HashMap$Entry.hashCode(HashMap.java:764)
at java.util.AbstractMap.hashCode(AbstractMap.java:557)
at java.util.HashMap.put(HashMap.java:418)
at java.util.HashSet.add(HashSet.java:194)
at java.util.AbstractCollection.addAll(AbstractCollection.java:318)
at org.hibernate.collection.PersistentSet.endRead(PersistentSet.java:329)
at
org.hibernate.engine.CollectionLoadContext.endLoadingCollection(CollectionLoadContext.java:183)
at
org.hibernate.engine.CollectionLoadContext.endLoadingCollections(CollectionLoadContext.java:268)
at
org.hibernate.engine.CollectionLoadContext.endLoadingCollections(CollectionLoadContext.java:249)
at org.hibernate.loader.Loader.endCollectionLoad(Loader.java:866)
at org.hibernate.loader.Loader.initializeEntitiesAndCollections(Loader.java:853)
at org.hibernate.loader.Loader.doQuery(Loader.java:717)
at org.hibernate.loader.Loader.doQueryAndInitializeNonLazyCollections(Loader.java:224)
at org.hibernate.loader.Loader.loadCollection(Loader.java:1985)
at org.hibernate.loader.collection.CollectionLoader.initialize(CollectionLoader.java:36)
at
org.hibernate.persister.collection.AbstractCollectionPersister.initialize(AbstractCollectionPersister.java:565)
at
org.hibernate.event.def.DefaultInitializeCollectionEventListener.onInitializeCollection(DefaultInitializeCollectionEventListener.java:60)
at org.hibernate.impl.SessionImpl.initializeCollection(SessionImpl.java:1716)
at
org.hibernate.collection.AbstractPersistentCollection.initialize(AbstractPersistentCollection.java:344)
at
org.hibernate.collection.AbstractPersistentCollection.read(AbstractPersistentCollection.java:86)
at org.hibernate.collection.PersistentSet.hashCode(PersistentSet.java:411)
at java.util.HashMap$Entry.hashCode(HashMap.java:764)
at java.util.AbstractMap.hashCode(AbstractMap.java:557)
at java.util.HashMap.put(HashMap.java:418)
at java.util.HashSet.add(HashSet.java:194)
at java.util.AbstractCollection.addAll(AbstractCollection.java:318)
at org.hibernate.collection.PersistentSet.endRead(PersistentSet.java:329)
at
org.hibernate.engine.CollectionLoadContext.endLoadingCollection(CollectionLoadContext.java:183)
at
org.hibernate.engine.CollectionLoadContext.endLoadingCollections(CollectionLoadContext.java:268)
at
org.hibernate.engine.CollectionLoadContext.endLoadingCollections(CollectionLoadContext.java:249)
at org.hibernate.loader.Loader.endCollectionLoad(Loader.java:866)
at org.hibernate.loader.Loader.initializeEntitiesAndCollections(Loader.java:853)
at org.hibernate.loader.Loader.doQuery(Loader.java:717)
at org.hibernate.loader.Loader.doQueryAndInitializeNonLazyCollections(Loader.java:224)
at org.hibernate.loader.Loader.loadCollection(Loader.java:1985)
at org.hibernate.loader.collection.CollectionLoader.initialize(CollectionLoader.java:36)
at
org.hibernate.persister.collection.AbstractCollectionPersister.initialize(AbstractCollectionPersister.java:565)
at
org.hibernate.event.def.DefaultInitializeCollectionEventListener.onInitializeCollection(DefaultInitializeCollectionEventListener.java:60)
at org.hibernate.impl.SessionImpl.initializeCollection(SessionImpl.java:1716)
at
org.hibernate.collection.AbstractPersistentCollection.forceInitialization(AbstractPersistentCollection.java:454)
at
org.hibernate.engine.StatefulPersistenceContext.initializeNonLazyCollections(StatefulPersistenceContext.java:755)
at org.hibernate.loader.Loader.doQueryAndInitializeNonLazyCollections(Loader.java:229)
at org.hibernate.loader.Loader.doList(Loader.java:2211)
at org.hibernate.loader.Loader.listIgnoreQueryCache(Loader.java:2095)
at org.hibernate.loader.Loader.list(Loader.java:2090)
at org.hibernate.loader.hql.QueryLoader.list(QueryLoader.java:388)
at org.hibernate.hql.ast.QueryTranslatorImpl.list(QueryTranslatorImpl.java:338)
at org.hibernate.engine.query.HQLQueryPlan.performList(HQLQueryPlan.java:172)
at org.hibernate.impl.SessionImpl.list(SessionImpl.java:1121)
at org.hibernate.impl.QueryImpl.list(QueryImpl.java:79)
at org.hibernate.impl.AbstractQueryImpl.uniqueResult(AbstractQueryImpl.java:804)
at org.jboss.test.DynamicTest.testSF(DynamicTest.java:83)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:40)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at com.intellij.rt.execution.application.AppMain.main(AppMain.java:90)
also note that commenting out this 3 lines makes it work:
Set roles = new HashSet();
roles.add(dummy);
lolo.put("roles",roles);
So I guess it's about resolving roles relationship during obtaing a user object
--
This message is automatically generated by JIRA.
-
If you think it was sent incorrectly contact one of the administrators:
http://opensource.atlassian.com/projects/hibernate/secure/Administrators....
-
For more information on JIRA, see:
http://www.atlassian.com/software/jira