-->
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.  [ 3 posts ] 
Author Message
 Post subject: Duplicate insert: map that has two keys with same value
PostPosted: Fri Jun 11, 2004 6:20 pm 
Newbie

Joined: Fri Jun 11, 2004 4:58 pm
Posts: 9
Hibernate Version:2.1.2

MyObject Mapping:
Code:
<hibernate-mapping>
    <class name="com.company.package.MyObject" table="MyObjects">
        <id name="id" column="ObjectID" type="string">
            <generator class="assigned"/>
        </id>
        <set name="properties" table="ObjectProperties" cascade="all">
            <key column="ObjectID"/>
            <many-to-many class="com.company.package.Property" column="PropertyID"/>
        </set>
    </class>
</hibernate-mapping>


Property Mapping:
Code:
<hibernate-mapping>
    <class name="com.company.package.Property" table="Properties">
        <id name="PropertyId" column="PropertyID" type="string">
            <generator class="assigned"/>
        </id>
        <map name="Map" table="PropertyMaps" cascade="all">
            <key column="PropertyID"/>
            <index-many-to-many class="com.company.package.MapName" column="MapNameID"/>
            <many-to-many class="com.company.package.MapValue" column="MapValueID"/>
        </map>
    </class>
</hibernate-mapping>


MapName Mapping:
Code:
<hibernate-mapping>
    <class name="com.company.package.MapName" table="MapNames">
        <id name="id" column="MapNameID" type="string">
            <generator class="assigned"/>
        </id>
    </class>
</hibernate-mapping>


MapValue Mapping:
Code:
<hibernate-mapping>
    <class name="com.company.package.MapName" table="MapValues">
        <id name="id" column="MapValueID" type="string">
            <generator class="assigned"/>
        </id>
    </class>
</hibernate-mapping>


Java Code:
Code:
MyObject o = new MyObject('123');

Property prop1 = new Property('456');
Map map1 = new Map('789');
map1.put(new MapName('name1'), new MapValue('val'));
prop1.setMap(map1);
o.addProperty(prop1);

Property prop2 = new Property('def');
Map map2 = new Map('ghi');
map2.put(new MapName('name2'), new MapValue('val'));
prop2.setMap(map2);
o.addProperty(prop2);

session.replicate(o, ReplicationMode.OVERWRITE);


Hibernate says it's doing the following (I've taken the liberty of manually hydrating the log entries for clarity):
Code:
Hibernate: select MyObjectID from MyObjects where MyObjectID = '123'
Hibernate: select PropertyID from Properties where PropertyID = '456'
Hibernate: select MapValueID from MapValues where MapValueID = 'val'
Hibernate: select PropertyID from Properties where PropertyID = 'def'
Hibernate: select MapValueID from MapValues where MapValueID = 'val'
Hibernate: insert into MyObjects (ObjectID) values ('123')
Hibernate: insert into Properties (PropertyID) values ('456')
Hibernate: insert into MapValues (MapValueID) values ('val')
Hibernate: insert into Properties (PropertyID) values ('def')
Hibernate: insert into MapValues (MapValueID) values ('val')
Exception Thrown:
com.jnetdirect.jsql.x: Violation of PRIMARY KEY constraint 'PK__MapValues__6DCC4D03'. Cannot insert duplicate key in object 'MapValues'.


Seems like Hibernate assumes that no two object instances with the same id will be committed to the database in the same transaction. Does this exception occur when persisting any map that contains two keys with the same value (same primary key)? This has only presented as a problem because we have to use a special MapValue instance to represent a null value (Hibernate will not persist a Map entry with null value). Since each of these special null object instances have the same id and the MapObject may contain several of them at the same time the exception presents itself. I suppose it could be an enhancement request to allow null values in Maps, but I see in JIRA that idea has already been discarded. Another possiblity might be to discard all but one of the duplicate insert statements during commit. Or maybe there is another strategy that I can use to acheive the same functionality?

It may be worth noting that all objects implement equals() and hashCode() around their respective id fields.

Any suggestions or work arounds are greatly appreciated!

Thanks! Keep up the great work Hibernate Team, we love your project!
-Alex


Top
 Profile  
 
 Post subject: Same problem seen with Hiberate 2.1.4
PostPosted: Sat Jun 12, 2004 12:02 pm 
Newbie

Joined: Fri Jun 11, 2004 4:58 pm
Posts: 9
The same issue is seen with Hibernate 2.1.4.


Top
 Profile  
 
 Post subject:
PostPosted: Sat Jun 12, 2004 2:27 pm 
Hibernate Team
Hibernate Team

Joined: Tue Aug 26, 2003 12:50 pm
Posts: 5130
Location: Melbourne, Australia
Clearly, you must use the same MapValue instance.


Top
 Profile  
 
Display posts from previous:  Sort by  
Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 3 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.