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

Jeffrey Vroom (JIRA) noreply at atlassian.com
Fri Jul 11 19:05:12 EDT 2008


    [ http://opensource.atlassian.com/projects/hibernate/browse/HHH-2299?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel#action_30642 ] 

Jeffrey Vroom commented on HHH-2299:
------------------------------------

We have also hit this problem when using dynamic models with hibernate.  It appears to be that there are two main problems with the code:

1) hashCode/equals for the dynamic objects hibernate returns is still using the AbstractMap's implementation which compares every key/value for equality.   The correct behavior in the docs is to use natural keys but there's no way to specify natural keys (as far as I know).  I think using the object's identity would be a better default (or as Maxim suggests use instance identity).   This would avoid the recursion and the error.

2) It also seems like the code should be marking the list as loaded before it puts it into the map.  That also would avoid this error without changing equals/hashCode.  


> 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
>          Issue Type: Bug
>          Components: core
>    Affects Versions: 3.2.1
>            Reporter: Boleslaw Dawidowicz
>         Attachments: hbTestCase.zip, 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