-->
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: Bi-directional mapping giving NonUniqueObjectException
PostPosted: Fri Oct 28, 2005 11:36 am 
Newbie

Joined: Tue Oct 25, 2005 2:34 pm
Posts: 12
For some reason I'm getting a NonUniqueObjectException from a many-one mapping I have. It's a simple mapping so I'm confused why it's causing this. I removed the Group mapping from the User mapping and it works fine, so I know it's that one. I understand why it would give the error, seeing as the Group holds a ref to the same User that's being updated. I don't see how to work around it. I've been looking online and in my books which all show the mapping correct. So if someone can point me the the right direction that would be great. Here's the mappings in question.

########### User Mapping #################################
<class name="com.collegevitae.User" table="CV_USER" discriminator-value="US">
<id name="id" column="cv_id">
<generator class="identity"/>
</id>

<discriminator column="cv_user_type" type="java.lang.String"/>

...... properties here .........

<subclass name="com.collegevitae.vitae.Vitae" discriminator-value="VT">

...... properties here .........

<many-to-one name="group" column="cv_vitae_group_id" class="com.collegevitae.vitae.Group"/>


...... properties here .........

</subclass>

..... other subclasses that work.....

################ End User Mapping ##############################

################# Group Mapping ##############################


<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">

<hibernate-mapping>
<class name="com.collegevitae.vitae.Group" table="CV_GROUP">
<id name="id" column="cv_id">
<generator class="identity"/>
</id>
<property name="hit" column="cv_hit"/>
<property name="name" column="cv_name"/>
<property name="hide" column="cv_hide"/>
<property name="restricted" column="cv_restricted"/>

<many-to-one name="category" column="cv_category_id" class="com.collegevitae.vitae.Category"/>

<set name="vitaes" inverse="true" order-by="cv_lastname" cascade="all-delete-orphan">
<key column="cv_vitae_group_id"/>
<one-to-many class="com.collegevitae.vitae.Vitae"/>
</set>

</class>
</hibernate-mapping>

######### End Group Mapping #####################################


Top
 Profile  
 
 Post subject:
PostPosted: Fri Oct 28, 2005 4:55 pm 
Regular
Regular

Joined: Mon Jul 26, 2004 2:28 pm
Posts: 86
Location: Pensacola, Florida
From the API documentation:

Quote:
This exception is thrown when an operation would break session-scoped identity. This occurs if the user tries to associate two different instances of the same Java class with a particular identifier, in the scope of a single Session.


It probably has less to do with your mapping and more to do with your usage. Since you didn't post the code between openSession and closeSession, I can only speculate. Here is one possible scenario:

Open session
Begin transaction
Load object with ID 5
Create new object, set its ID to 5
Attempt to save new object, resulting in NonUniqueObjectException
...

Another problem may be that you have two rows in your database with the same value in the column you have mapped to your ID. This might happen if you don't have a UNIQUE constraint on your ID column and the data got messed up somehow (double-save, for example). It could also happen on a table with a composite key, if there was no UNIQUE constraint containing all of the key columns.

- Jesse


Top
 Profile  
 
 Post subject:
PostPosted: Fri Oct 28, 2005 5:36 pm 
Newbie

Joined: Tue Oct 25, 2005 2:34 pm
Posts: 12
My save code looks like such:



public void saveVitae(com.collegevitae.vitae.Vitae vitae) {
org.hibernate.Transaction tx = this.session.beginTransaction();
try {
this.session.saveOrUpdate(vitae);
tx.commit();
} catch (org.hibernate.HibernateException e) {
this.log.error(e.toString());
tx.rollback();
}
}


Here's the code that uses the method above:

com.collegevitae.db.VitaeRepository vitaeRepository = (com.collegevitae.db.VitaeRepository) reg.getService(com.collegevitae.db.VitaeRepository.class);
com.collegevitae.db.GroupRepository groupRepository = (com.collegevitae.db.GroupRepository) reg.getService(com.collegevitae.db.GroupRepository.class);
this.getVitae().setGroup(groupRepository.getGroup(this.getGroupid()));
vitaeRepository.saveVitae(this.getVitae());


I'm using HiveMind and it closes the Session after each request. So the above code loads a Group by id and then sets that group in the Vitae. Then the Vitae is saved. After that the request is finished and closed. The only thing I can think of is that when the Group is loaded by id then that causes the Vitae to be loaded as well, but why would it still do this when the Group that's loaded doesn't have a Vitae in it? The above methods work just fine for everything else, it's just when the Group is set in the Vitae that it causes this problem. If I remove the part that set's the Group the Vitae saves just fine.


Top
 Profile  
 
 Post subject:
PostPosted: Fri Oct 28, 2005 8:13 pm 
Newbie

Joined: Tue Oct 25, 2005 2:34 pm
Posts: 12
Another strange thing on this. When I save the Vitae I get the org.hibernate.NonUniqueObjectException every time. But if I change the username property of the Vitae and save it saves just fine. No duplicates or anything. But if I change the email property and save I get the error. So why would it save on username property but not the other properties?


Top
 Profile  
 
 Post subject:
PostPosted: Fri Oct 28, 2005 8:17 pm 
Newbie

Joined: Tue Oct 25, 2005 2:34 pm
Posts: 12
rizenine wrote:
The above methods work just fine for everything else, it's just when the Group is set in the Vitae that it causes this problem. If I remove the part that set's the Group the Vitae saves just fine.


Just a correction here. It's not just if the Group is set in the Vitae, it's if the mapping is even there. If I remove the mapping all works fine again.


Top
 Profile  
 
 Post subject:
PostPosted: Sat Oct 29, 2005 6:36 pm 
Beginner
Beginner

Joined: Thu Jan 22, 2004 8:22 pm
Posts: 48
You don't really show enough to tell exactly where the problem is. We'd need the text of the exception and all the code involved in the failing case. For example in the code you've shown so far I can't see where the Group is coming from. We also can't see how the Vitae is being obtained. Are both of these objects being loaded usng the current session at the time they're requested. Boiling all the code down to a single method without calls to anything but Hibernate or standard Java library code is best.

I can say that another common way to get this error is to have a instance that was loaded from a previous session and instance loaded from the current session that represent teh same row. If you accidentally make use of the transient instance and you might get this exception.


Top
 Profile  
 
 Post subject:
PostPosted: Sun Oct 30, 2005 10:53 am 
Newbie

Joined: Tue Oct 25, 2005 2:34 pm
Posts: 12
That would be a lot of code to post. I can tell you how it works. Each request is a new session that's closed by HiveMind at the end of the request/thread cleanup. Each save, update, delete is done in a single transaction. So if I do a couple saves and a few loads, they're all done in the same session, but separate transactions. In this case I'm only loading the Group and Category on each request. The Vitae that's being changed was loaded from the last session. What I will do is post the entire mapping of each object and you can tell me if that helps. The reason I'm posting the mapping is because what you'll see is several subclasses are mapped to that User class including Vitae and Admin. But whenever I add the group mapping, that causes any subclass of user to give the NonUniqueObjectException exception. Which makes me think it's a mapping issue. So when I add the many-one mapping for Group to Vitae subclass then Admin doesn't update, and I can tell you for sure that nothing is loaded but the Admin class under the admin edit section. Plus this is my first try at subclasses, so I'm probably doing something wrong. I have many many-one mappings that have no trouble at all, so I don't see why this one isn't working. The only difference is that this one is in a subclass.


<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">

<hibernate-mapping>
<class name="com.collegevitae.User" table="CV_USER" discriminator-value="US">
<id name="id" column="cv_id">
<generator class="identity"/>
</id>

<discriminator column="cv_user_type" type="java.lang.String"/>

<property name="role" column="cv_role"/>
<property name="disabled" column="cv_disabled"/>
<property name="locked" column="cv_locked"/>
<property name="attempts" column="cv_attempts"/>
<property name="username" column="cv_username"/>
<property name="password" column="cv_password"/>
<property name="firstname" column="cv_firstname"/>
<property name="middlename" column="cv_middlename"/>
<property name="lastname" column="cv_lastname"/>
<property name="address" column="cv_address"/>
<property name="city" column="cv_city"/>
<property name="state" column="cv_state"/>
<property name="zip" column="cv_zip"/>
<property name="phone" column="cv_phone"/>
<property name="fax" column="cv_fax"/>
<property name="cell" column="cv_cell"/>
<property name="email" column="cv_email"/>
<property name="lastLogin" column="cv_lastLogin"/>
<property name="created" column="cv_created"/>

<subclass name="com.collegevitae.vitae.Vitae" discriminator-value="VT">
<property name="hit" column="cv_vitae_hit"/>
<property name="publish" column="cv_vitae_publish"/>
<property name="updated" column="cv_vitae_updated"/>
<property name="graduate" column="cv_vitae_graduate"/>
<property name="info" column="cv_vitae_info"/>
<property name="objective" column="cv_vitae_objective"/>

<many-to-one name="group" column="cv_vitae_group_id" class="com.collegevitae.vitae.Group"/>

<many-to-one name="workbook" column="cv_vitae_workbook_id" class="com.collegevitae.vitae.WorkBook" cascade="all"/>

<many-to-one name="life" column="cv_vitae_life_id" class="com.collegevitae.vitae.Life" cascade="all"/>

<set name="education" inverse="true" order-by="cv_order" cascade="all-delete-orphan">
<key column="cv_user_id"/>
<one-to-many class="com.collegevitae.vitae.Education"/>
</set>

<set name="experience" inverse="true" order-by="cv_order" cascade="all-delete-orphan">
<key column="cv_user_id"/>
<one-to-many class="com.collegevitae.vitae.Experience"/>
</set>

<set name="references" inverse="true" order-by="cv_order" cascade="all-delete-orphan">
<key column="cv_user_id"/>
<one-to-many class="com.collegevitae.vitae.Reference"/>
</set>

<set name="messages" inverse="true" order-by="cv_created" cascade="all-delete-orphan">
<key column="cv_user_id"/>
<one-to-many class="com.collegevitae.vitae.Message"/>
</set>

<set name="invites" inverse="true" order-by="cv_invite_expires" cascade="all-delete-orphan">
<key column="cv_user_id"/>
<one-to-many class="com.collegevitae.vitae.Invite"/>
</set>
</subclass>

<subclass name="com.collegevitae.admin.Admin" discriminator-value="AD">
<property name="master" column="cv_admin_master"/>
</subclass>

<subclass name="com.collegevitae.visitor.Visitor" discriminator-value="VS">
<property name="company" column="cv_visitor_company"/>
</subclass>

<subclass name="com.collegevitae.vitae.Invite" discriminator-value="IN">
<property name="hit" column="cv_invite_hit"/>
<property name="description" column="cv_invite_description"/>
<property name="inviteemail" column="cv_invite_email"/>
<property name="code" column="cv_invite_code"/>
<property name="expires" column="cv_invite_expires"/>

<many-to-one name="vitae" column="cv_invite_user_id" class="com.collegevitae.vitae.Vitae"/>
</subclass>

</class>
</hibernate-mapping>






<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">

<hibernate-mapping>
<class name="com.collegevitae.vitae.Group" table="CV_GROUP">
<id name="id" column="cv_id">
<generator class="identity"/>
</id>
<property name="hit" column="cv_hit"/>
<property name="name" column="cv_name"/>
<property name="hide" column="cv_hide"/>
<property name="restricted" column="cv_restricted"/>

<many-to-one name="category" column="cv_category_id" class="com.collegevitae.vitae.Category"/>

<set name="vitaes" inverse="true" order-by="cv_lastname" cascade="all-delete-orphan">
<key column="cv_vitae_group_id"/>
<one-to-many class="com.collegevitae.vitae.Vitae"/>
</set>

</class>
</hibernate-mapping>


<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">

<hibernate-mapping>
<class name="com.collegevitae.vitae.Category" table="CV_CATEGORY">
<id name="id" column="cv_id">
<generator class="identity"/>
</id>
<property name="hit" column="cv_hit"/>
<property name="name" column="cv_name"/>
<property name="hide" column="cv_hide"/>

<set name="groups" inverse="true" order-by="cv_name" cascade="all-delete-orphan">
<key column="cv_category_id"/>
<one-to-many class="com.collegevitae.vitae.Group"/>
</set>

</class>
</hibernate-mapping>


Top
 Profile  
 
 Post subject:
PostPosted: Wed Nov 02, 2005 10:19 am 
Newbie

Joined: Tue Oct 25, 2005 2:34 pm
Posts: 12
WOW HOO!!! Got it fixed. You guys where right. It was a usage issue. Like I said there's a lot of code in this, and it goes every where. I decided to stop and take some time to really back track things. Found I was loading twice and learned some things I didn't know. Thanks for the direction.


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.