[
http://opensource.atlassian.com/projects/hibernate/browse/HHH-2299?page=c...
]
Gail Badner commented on HHH-2299:
----------------------------------
Basically, entities are modeled using HashMap objects, rather than an object of an
explicitly defined class. Each entity property is modeled as a Map.Entry using the
property name and value as the key-value pair.
I have verified that the exception does not arise when the test is converted to use
"pojo" entity mode.
A PortalUser "theUser" and a PortalRole "theRole" are created as
HashMap objects. theRole is added to the theUser's set of roles and theUser is added
to theRole's set of users. A Query is used to read the user.
The following leads to the exception:
1) "theUser" is read from the DB into a HashMap. Since a PortalUser has a
non-lazy set of PortalRoles, theUser's roles are read from the DB into an ArrayList in
a PersistentSet "roles", containing only theRole. Since a PortalRole has a lazy
set of PortalUsers. theRole's users are not read.
2) The last step to initialize a PersistentSet involves adding the elements from an
ArrayList into a HashSet. When computing the hash code for theUser's roles, the
hashCode method is ultimately called on theRole's "users" entry which is an
uninitialized PersistentSet. PersistentSet.hashCode() forces initialization of
theRole's users, even though it is supposed to be lazy. theRole's users include
only theUser.
3) The last step to initialize theRole's users, also a PersistentSet, is to add the
user elements from an ArrayList to a HashSet. In the process, the hashCode() method on
theUser's roles PersistentSet, again forcing initialization of the original user's
set of roles. Because, that user's roles are already in the process of being
initialized, the exception is thrown.
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