This seems to be a bug. Please submit to JIRA. TIA

St-Pierre Philip wrote:

I have a many-to-many association between two objects. The association table contains the idbag identifier, the identifier of each associated objects and additionnal fields (Collection of components). Here is the association table:

ID_EC NUMBER(28) -->idbag identifier
ID_COO NUMBER(28) -->associated object identifier
ID_EA NUMBER(28) -->associated object identifier
REF_SYS_UTIL_COORD_EC VARCHAR2(19) -->additionnal field
CODE_INITIATEUR_CTRL VARCHAR2(20) -->additionnal field
NO_VERSION_CTRL NUMBER(6) -->additionnal field
DATE_CREATION_CTRL TIMESTAMP(6) -->additionnal field
DATE_DERN_MAJ_CTRL TIMESTAMP(6) -->additionnal field


There is a composite unique constraint on the keys of the contained objects, ID_COO and ID_EA. ID_EC (idbag identifier) is not part of the unique constraint and should not be, because this would allow an object to contain an other object twice (We don't want that).

The problem is that I can't remove an object from the collection (the idbag) because this create a unique constraint violation:

Hibernate: delete from PER.T_ENTITE_COORDONNEE_L where ID_EC=?
Hibernate: update PER.T_ENTITE_COORDONNEE_L set CODE_INITIATEUR_CTRL=?, REF_SYS_UTIL_COORD_EC=?, ID_COO=? where ID_EC=?
[WARN] JDBCExceptionReporter - -SQL Error: 1, SQLState: 23000
[ERROR] JDBCExceptionReporter - -ORA-00001: unique constraint (PER.UK_ENTITE_COORDONNEE_L) violated


[ERROR] JDBCExceptionReporter - -could not update collection rows: [com.iris.business.component.util.EntiteAffaire.entiteCoordonnees#14680000060404] <java.sql.SQLException: ORA-00001: unique constraint (PER.UK_ENTITE_COORDONNEE_L) violated

>java.sql.SQLException: ORA-00001: unique constraint (PER.UK_ENTITE_COORDONNEE_L) violated

While debuging i saw how the identifierBag works. It keeps the idbag identifiers in a HashMap (identifiers) and the contained objects in a ArrayList (values). Each identifier maps to the right object by keeping its index (in the key of the HashMap) in the array list.

For example, assume that i remove the first object in the ArrayList values. What happen, is that the object will be removed from the ArrayList values at the index "0" an all other objects will be shifted one index back, but identifiers in the HasMap will not be updated. That means that each object will take the identifier of its predecessor and the last identifier will not be pointing at an object anymore.

What we have in the idbag is:
Before we remove the object:
Identifier: 0 -> component: a
Identifier: 1 -> component: b
Identifier: 2 -> component: c

After removing the object a
Identifier: 0 -> component: b
Identifier: 1 -> component: c
Identifier: 2 ->

But while updating the association table, Hibernate try to update the the row with the identifier 0 by inserting (Identifier: 0 -> component: b), but we already have the component b in the database (Identifier: 1 -> component: b) and the component b has a unique contraint, so a unique constraint violation occur.

Here is the code, it is quite simple (Sorry for the code in french, i am french speaking):
EntiteAffaire ea = (EntiteAffaire) session.load(EntiteAffaire.*class*, idEA);


Iterator itEnt = ea.getEntiteCoordonnees().iterator();
*if*(itEnt.hasNext())
{
        EntiteCoordonnee entCoord = (EntiteCoordonnee) itEnt.next();
        itEnt.remove();
}

And the mapping:
<class name="com.iris.business.component.util.EntiteAffaire" schema="PER" table="T_ENTITE_AFFAIRE">
<id name="id" type="string" column="ID_EA" unsaved-value="null">
<generator class="com.iris.infrastructure.services.identification.UniqueIDProviderHibernateImpl"/>


</id>

<property name="codeInitiateur" type="string" column="CODE_INITIATEUR_CTRL"/>

<idbag name="entiteCoordonnees" schema="PER" table="T_ENTITE_COORDONNEE_L" lazy="true" cascade="all" >

<collection-id column="ID_EC" type="string">
<generator class="com.iris.infrastructure.services.identification.UniqueIDProviderHibernateImpl" />
</collection-id>


<key column="ID_EA"/>
<composite-element class="com.iris.business.component.util.EntiteCoordonnee">
<property name="codeInitiateur" type="string" column="CODE_INITIATEUR_CTRL"/>


<property name="utilisation" column="REF_SYS_UTIL_COORD_EC" type="string" not-null="true"/>

<many-to-one name="coordonnee"
column="ID_COO"
class="com.iris.business.component.util.CoordonneeUtil"
not-null="true" cascade="all"/>
</composite-element>
</idbag>
</class>


Well it seems that we can't remove an object from a idBag if the association table contains a unique key.
I Hope i was clear enough in my explanation.


Thanks!!

*/Philip St-Pierre/*
Analyste-Programmeur (Infrastructure)
+ [EMAIL PROTECTED]



--
Gavin King
+61 410534454

Hibernate
[EMAIL PROTECTED]
http://hibernate.org

JBoss Inc
[EMAIL PROTECTED]
http://jboss.com



-------------------------------------------------------
This SF.Net email is sponsored by: IBM Linux Tutorials
Free Linux tutorial presented by Daniel Robbins, President and CEO of
GenToo technologies. Learn everything from fundamentals to system
administration.http://ads.osdn.com/?ad_id=1470&alloc_id=3638&op=click
_______________________________________________
hibernate-devel mailing list
[EMAIL PROTECTED]
https://lists.sourceforge.net/lists/listinfo/hibernate-devel

Reply via email to