[hibernate-issues] [Hibernate-JIRA] Commented: (HHH-2299) dynamic-map entity mode mappings with relationships rise lazy initialization during performing query

Gail Badner (JIRA) noreply at atlassian.com
Tue Jan 2 17:06:44 EST 2007


    [ http://opensource.atlassian.com/projects/hibernate/browse/HHH-2299?page=comments#action_25738 ] 

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@"/>-->
>        <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@"/>-->
>           <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>
>        <!-- at 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@"/>-->
>           <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@"/>-->
>       <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@"/>-->
>          <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.jspa
-
For more information on JIRA, see:
   http://www.atlassian.com/software/jira




More information about the hibernate-issues mailing list