-->
These old forums are deprecated now and set to read-only. We are waiting for you on our new forums!
More modern, Discourse-based and with GitHub/Google/Twitter authentication built-in.

All times are UTC - 5 hours [ DST ]



Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 8 posts ] 
Author Message
 Post subject: idbag duplicates rows
PostPosted: Mon Jan 26, 2004 12:09 pm 
Regular
Regular

Joined: Tue Oct 28, 2003 8:25 am
Posts: 72
Location: Belgium
Hi,

Looks like I've encountered a case when idbag duplicates some values.

Let's imagine this simple case, we have 3 tables: SELECTION, SELECTED and FIELD.

SELECTED is the middle table for the many-to-many relation between SELECTION and FIELD.

Now I load a selection ad add the first field to it. Everything works fine. Then I do it again; I reload the same selection and add another field. The new field is added but the old one have been duplicated, leaving me with a selection that has three fields instead of one.

Anybody have ever heard of such a problem ?

Thanks,
Ludovic


Top
 Profile  
 
 Post subject:
PostPosted: Mon Jan 26, 2004 12:22 pm 
Hibernate Team
Hibernate Team

Joined: Tue Sep 09, 2003 2:10 pm
Posts: 3246
Location: Passau, Germany
Most likely a problem with your unsaved-value mapping I suspect. Show your mappings.


Top
 Profile  
 
 Post subject:
PostPosted: Mon Jan 26, 2004 12:35 pm 
Regular
Regular

Joined: Tue Oct 28, 2003 8:25 am
Posts: 72
Location: Belgium
Here is the mapping of the Selection and Field objects. The relation is unidirectional:

Code:
   <class name="pkg.Selection" table="SELECTION" lazy="true">

        <id name="selectionId" column="ID_SELECTION" type="long" unsaved-value="0">
        ...

        <idbag name="fields" table="SELECTED" cascade="all" lazy="true" >
            <cache usage="nonstrict-read-write"/>
            <collection-id column="ID_SELECTED" type="long">
                <generator class="sequence">
                    <param name="sequence">SEQ_SELECTED</param>
                </generator>
            </collection-id>

            <key column="FK_SELECTION"/>
            <many-to-many class="pkg.Field" column="FK_FIELD"/>
        </idbag>

    </class>


    <class name="pkg.Field" table="FIELD" lazy="true">
        <id name="fieldId" column="ID_FIELD" type="long" unsaved-value="0">
        ...
    </class>


Insertion code looks like this:

Code:
    Selection sel = (Selection) session.load(Selection.class, new Long(pk));
    sel.getFields().add(session.load(Field.class, new Long(fieldFk1)));
    session.flush();
    session.connection().commit();

    ...

    Selection sel = (Selection) session.load(Selection.class, new Long(pk));
    sel.getFields().add(session.load(Field.class, new Long(fieldFk2)));
    session.flush();
    session.connection().commit();



Between thie first and the second load, sometimes a new session is used, sometimes not. And sometimes it works fine, sometimes not.

Thanks,
Ludovic


Top
 Profile  
 
 Post subject:
PostPosted: Mon Jan 26, 2004 12:39 pm 
Hibernate Team
Hibernate Team

Joined: Tue Sep 09, 2003 2:10 pm
Posts: 3246
Location: Passau, Germany
Okay, now I suspect a problem with your equals method. Use your debugger and check if the list does not actually contain duplicate elements after the add.


Top
 Profile  
 
 Post subject:
PostPosted: Mon Jan 26, 2004 2:11 pm 
Hibernate Team
Hibernate Team

Joined: Tue Aug 26, 2003 12:50 pm
Posts: 5130
Location: Melbourne, Australia
Bags permit duplicate values. So this behaviour is expected, right?


Top
 Profile  
 
 Post subject:
PostPosted: Mon Jan 26, 2004 2:36 pm 
Regular
Regular

Joined: Tue Oct 28, 2003 8:25 am
Posts: 72
Location: Belgium
Mmm... I agree this behaviour could be legal if I added multiple times the same object to the idbag but my code is written to avoid this and I'm pretty sure it's OK.

I still don't understand how the idbag "calculates" the delta between objects that were already in the bag at load and the ones that were added afterward. It seems that it becomes confused (or that I confuse it) about references coming from the DB and the ones freshly added.

Can the session closing/reattachment have some impact on this ?


Top
 Profile  
 
 Post subject:
PostPosted: Tue Jan 27, 2004 9:13 am 
Regular
Regular

Joined: Tue Oct 28, 2003 8:25 am
Posts: 72
Location: Belgium
After some debugging of the Hibernate code, I've found something that does not look normal:

IdentifierBag.preInsert() uses the identifiers map to check if it contains integers it generates as keys. I deducted from this method that the identifiers map should contains Integers as keys and Long as value (at least in my case).

At some point, when the preInsert method is called the identifiers map contains Field entities (my own class) as key and null as value.

Looks like something went wrong; since the map does not contain already generated identifiers, it regenerates them and then re-inserts objects.

The only method I found which is not inserting itergers as keys in the map is this contructor:

Code:
public IdentifierBag(SessionImplementor session, CollectionPersister persister, Serializable disassembled, Object owner)


I tried to replace lines 68 to 71 with:

Code:
         identifiers.put(
            new Integer(j++),
            value
         );


and insertion then worked fine but this broke deletion:

Code:
java.lang.ClassCastException
        at net.sf.hibernate.type.LongType.set(LongType.java:32)
        at net.sf.hibernate.type.NullableType.nullSafeSet(NullableType.java:48)
        at net.sf.hibernate.type.NullableType.nullSafeSet(NullableType.java:35)
        at net.sf.hibernate.collection.AbstractCollectionPersister.writeRowSelect(AbstractCollectionPersister.java:404)
        at net.sf.hibernate.collection.AbstractCollectionPersister.deleteRows(AbstractCollectionPersister.java:579)
        at net.sf.hibernate.impl.ScheduledCollectionUpdate.execute(ScheduledCollectionUpdate.java:47)
        at net.sf.hibernate.impl.SessionImpl.executeAll(SessionImpl.java:2308)
        at net.sf.hibernate.impl.SessionImpl.execute(SessionImpl.java:2264)
        at net.sf.hibernate.impl.SessionImpl.flush(SessionImpl.java:2187)
...


Gavin, do you have any hint on this ?


Top
 Profile  
 
 Post subject:
PostPosted: Wed Jan 28, 2004 4:29 am 
Regular
Regular

Joined: Tue Oct 28, 2003 8:25 am
Posts: 72
Location: Belgium
For eventual future references: there was a bug in the idbag and have been fixed.

See http://opensource.atlassian.com/project ... key=HB-653


Top
 Profile  
 
Display posts from previous:  Sort by  
Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 8 posts ] 

All times are UTC - 5 hours [ DST ]


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum

Search for:
© Copyright 2014, Red Hat Inc. All rights reserved. JBoss and Hibernate are registered trademarks and servicemarks of Red Hat, Inc.