[hibernate-issues] [Hibernate-JIRA] Commented: (HHH-2498) Lazy Inverse Map Bug?

Robert Nice (JIRA) noreply at atlassian.com
Thu Jun 4 00:45:13 EDT 2009


    [ http://opensource.atlassian.com/projects/hibernate/browse/HHH-2498?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=33329#action_33329 ] 

Robert Nice commented on HHH-2498:
----------------------------------

This is almost certainly some strange bug.

If you call remove on such a regular lazy collection before otherwise touching it, there is one operation assigned to a DelayedOperation class. It either never gets run, or the index cannot be looked up because initialization changes the index object. The example above uses a long, so I doubt that's it.

My solution was to simply mark the collection as extra lazy as this takes a different code path, otherwise get the object before removing it; but there's certainly something funky going on. I'll try and reproduce a test case.

> Lazy Inverse Map Bug?
> ---------------------
>
>                 Key: HHH-2498
>                 URL: http://opensource.atlassian.com/projects/hibernate/browse/HHH-2498
>             Project: Hibernate Core
>          Issue Type: Bug
>    Affects Versions: 3.2.1, 3.2.2
>         Environment: Hibernate 3.2.2, Java5, MySQL 5 (InnoDB)
>            Reporter: CannonBall
>            Priority: Minor
>
> Mapping documents:
> <hibernate-mapping>
>     <class name="scratchpad.hibernate.A">
>         <id name="id">
>             <generator class="assigned"/>
>         </id>
>         <map name="bs" cascade="all-delete-orphan" inverse="true">
>             <key column="aId"/>
>             <map-key type="long" column="cId"/>
>             <one-to-many class="scratchpad.hibernate.B"/>
>         </map>
>     </class>
>     <class name="scratchpad.hibernate.B">
>         <id name="id">
>             <generator class="assigned"/>
>         </id>
>         <many-to-one name="a" class="scratchpad.hibernate.A" column="aId"/>
>         <many-to-one name="c" class="scratchpad.hibernate.C" column="cId" not-null="true"/>
>     </class>
>    
>     <class name="scratchpad.hibernate.C">
>         <id name="id">
>             <generator class="assigned"/>
>         </id>
>     </class>
> </hibernate-mapping>
> Code between sessionFactory.openSession() and session.close():
>         long aId = 1l;
>         long bId = 2l;
>         long cId = 3l;
>         SessionFactory factory = new Configuration().configure()
>                 .buildSessionFactory();
>         try {
>             Session s = factory.openSession();
>             try {
>                 Transaction tx = s.beginTransaction();
>                 try {
>                     C c = new C(cId);
>                     s.save(c);
>                     A a = new A(aId);
>                     B b = new B(bId);
>                     b.setC(c);
>                     b.setA(a);
>                     a.getBs().put(cId, b);
>                     s.save(a);
>                     tx.commit();
>                 } catch (Exception e) {
>                     try {
>                         tx.rollback();
>                     } catch (Exception e2) {
>                         // do nothing
>                     }
>                     throw e;
>                 }
>             } finally {
>                 s.close();
>             }
>             s = factory.openSession();
>             try {
>                 Transaction tx = s.beginTransaction();
>                 try {
>                     A a = (A) s.load(A.class, aId);
>                     a.getBs().remove(cId);
>                    
>                     tx.commit();
>                 } catch (Exception e) {
>                     try {
>                         tx.rollback();
>                     } catch (Exception e2) {
>                         // do nothing
>                     }
>                     throw e;
>                 }
>             } finally {
>                 s.close();
>             }
>         } finally {
>             factory.close();
>         }
> Name and version of the database you are using: MySQL 5.0.33
> The generated SQL (show_sql=true):
> Hibernate: select b_.id, b_.aId as aId1_, b_.cId as cId1_ from B b_ where b_.id=?
> Hibernate: insert into C (id) values (?)
> Hibernate: insert into A (id) values (?)
> Hibernate: insert into B (aId, cId, id) values (?, ?, ?)
> Hibernate: select a0_.id as id0_0_ from A a0_ where a0_.id=?
> Hibernate: select bs0_.aId as aId1_, bs0_.id as id1_, bs0_.cId as cId1_, bs0_.id as id1_0_, bs0_.aId as aId1_0_, bs0_.cId as cId1_0_ from B bs0_ where bs0_.aId=?
> I've been having a confusing problem shown above, whereby A has a Map of Bs indexed using the id from an association with C. This Map is inversely mapped for A and with 'Cascade Delete Orphan'. In the second opened session above, where B is removed from A's Map and thus orphaned, B will not be deleted. I have observed B is only deleted if I either set 'lazy="false"' for A's Map or make an interaction with A's Map in the code (before B's removal) like 'a.getBs().get(cId)'. I suspect the lazy intializer is not initializing correctly in the above scenario.
> The above scenario does not happen if A's Map is not inversely mapped but B's many-to-one with A is.
> Can somebody shed some light on whether this is me using Hibernate incorrectly or is a bug?

-- 
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