-->
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.  [ 17 posts ]  Go to page 1, 2  Next
Author Message
 Post subject: net.sf.hibernate.NonUniqueObjectException
PostPosted: Thu Aug 19, 2004 8:16 am 
Newbie

Joined: Thu Aug 19, 2004 7:57 am
Posts: 14
I've got an interesting bug in the way I'm using Hibernate. I'm getting a when I try and cascade delete multiple object within a transaction. So, with my code looking like this:
Code:
        PersistenceManager.beginTransaction();
        PersistenceManager.saveOrUpdate(product);
        PersistenceManager.saveOrUpdate(customer);
        PersistenceManager.saveOrUpdate(proposal);
        PersistenceManager.commitTransaction();
   /** do some validations here */
        PersistenceManager.beginTransaction();
        PersistenceManager.delete(proposal);
        PersistenceManager.delete(customer);
        PersistenceManager.delete(product);
        PersistenceManager.commitTransaction();

I get a a net.sf.hibernate.NonUniqueObjectException exception when stepping over the PersistenceManager.delete(customer); snippet. (See stack trace below). Now if I modify my code to commit after every delete like this:
Code:
        PersistenceManager.saveOrUpdate(product);
        PersistenceManager.saveOrUpdate(customer);
        PersistenceManager.saveOrUpdate(proposal);
        PersistenceManager.commitTransaction();
   /** do some validations here */
        PersistenceManager.beginTransaction();
        PersistenceManager.delete(proposal);
        PersistenceManager.commitTransaction();
        PersistenceManager.beginTransaction();
        PersistenceManager.delete(customer);
        PersistenceManager.commitTransaction();
        PersistenceManager.beginTransaction();
        PersistenceManager.delete(product);
        PersistenceManager.commitTransaction();

Things work just fine and all the deletes cascade properly. Can anyone help me?

Hibernate version: 2.1.6
Full stack trace of any exception that occurs:
net.sf.hibernate.NonUniqueObjectException: a different object with the same identifier value was already associated with the session: ff808082fe76b83200fe76b836400002, of class: com.ap.ptool.biz.Customer
at net.sf.hibernate.impl.SessionImpl.delete(SessionImpl.java:1141)
at com.ap.ptool.persistence.PersistenceManager.delete(PersistenceManager.java:92)
at com.ap.ptool.biz.tests.unit.SolutionTest.testCreateSolutionWithProposedProductOne_Ok(SolutionTest.java:48)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:324)
at junit.framework.TestCase.runTest(TestCase.java:154)
at junit.framework.TestCase.runBare(TestCase.java:127)
at junit.framework.TestResult$1.protect(TestResult.java:106)
at junit.framework.TestResult.runProtected(TestResult.java:124)
at junit.framework.TestResult.run(TestResult.java:109)
at junit.framework.TestCase.run(TestCase.java:118)
at junit.framework.TestSuite.runTest(TestSuite.java:208)
at junit.framework.TestSuite.run(TestSuite.java:203)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:421)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:305)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:186)


Name and version of the database you are using:
MySQL v4

Debug level Hibernate log excerpt:

Code:

_________________
Andy Czerwonka


Top
 Profile  
 
 Post subject:
PostPosted: Thu Aug 19, 2004 9:21 am 
Senior
Senior

Joined: Tue Sep 23, 2003 8:18 am
Posts: 137
Location: Johannesburg, South Africa
Hi Andy,

Something I found useful, is to not overuse objects within Sessions too much.

If you could, can you tell us if there is a relationship between any of the objects you are updating/deleting?

It looks to me like you're trying to tell the PM to delete the same object twice. Not completely sure of that. Show us the relationships and that may give us a better idea.

-G


Top
 Profile  
 
 Post subject:
PostPosted: Thu Aug 19, 2004 9:48 am 
Newbie

Joined: Thu Aug 19, 2004 7:57 am
Posts: 14
Brannor McThife wrote:
Hi Andy,

Something I found useful, is to not overuse objects within Sessions too much.

If you could, can you tell us if there is a relationship between any of the objects you are updating/deleting?

It looks to me like you're trying to tell the PM to delete the same object twice. Not completely sure of that. Show us the relationships and that may give us a better idea.

-G

Brannor,

Thanks for taking an interest. I've traversed all the topics on this issue and I can't seem to understand what's happening.

Yes, all these operations are within one session. I close the session on commit, which makes most sense as these are application-facade level operations.

Here's an example of my object graph...

http://www.arcticpenguin.ca/class_diagram.png

_________________
Andy Czerwonka


Top
 Profile  
 
 Post subject:
PostPosted: Thu Aug 19, 2004 9:54 am 
Senior
Senior

Joined: Tue Sep 23, 2003 8:18 am
Posts: 137
Location: Johannesburg, South Africa
Can you post your hibernate mapping for Proposal and Customer?

It looks like the call to delete the Proposal is cascading down to delete the Customer, and then you tell it to delete the Customer again.

-G


Top
 Profile  
 
 Post subject:
PostPosted: Thu Aug 19, 2004 10:07 am 
Newbie

Joined: Thu Aug 19, 2004 7:57 am
Posts: 14
Brannor McThife wrote:
Can you post your hibernate mapping for Proposal and Customer?

It looks like the call to delete the Proposal is cascading down to delete the Customer, and then you tell it to delete the Customer again.

-G


Sure.

http://www.arcticpenguin.ca/files/Proposal.hbm.xml
http://www.arcticpenguin.ca/files/Customer.hbm.xml

They're all there... Just use the Class name for the mapping document.

Thanks again and in advance.

_________________
Andy Czerwonka


Top
 Profile  
 
 Post subject:
PostPosted: Thu Aug 19, 2004 10:17 am 
Senior
Senior

Joined: Tue Sep 23, 2003 8:18 am
Posts: 137
Location: Johannesburg, South Africa
Just a quick thought while I examine the mappings, have you tried changing the order of your delete statements?

-G


Top
 Profile  
 
 Post subject:
PostPosted: Thu Aug 19, 2004 10:22 am 
Senior
Senior

Joined: Tue Sep 23, 2003 8:18 am
Posts: 137
Location: Johannesburg, South Africa
Maybe I'm not reading properly, but I don't see a SET in Customer linking it to Proposals, i.e. the other side of the 1-M relationship. ?

-G


Top
 Profile  
 
 Post subject:
PostPosted: Thu Aug 19, 2004 10:25 am 
Newbie

Joined: Thu Aug 19, 2004 7:57 am
Posts: 14
Brannor McThife wrote:
Maybe I'm not reading properly, but I don't see a SET in Customer linking it to Proposals, i.e. the other side of the 1-M relationship. ?

-G


Correct. It's a unidirectional association. You can say proposal.getCustomer(), but you can't say customer.getProposals(). This is intended.

_________________
Andy Czerwonka


Top
 Profile  
 
 Post subject:
PostPosted: Thu Aug 19, 2004 10:33 am 
Senior
Senior

Joined: Tue Sep 23, 2003 8:18 am
Posts: 137
Location: Johannesburg, South Africa
Ok, understood.

Without writing out some code to test it, I'd go with the .delete(proposal) accessing the customer object as well, and as such causing the exception when you call the .delete(customer). Try deleting the customer first (might not work because of the unidirectional constraint).

If not, I'll try write some code to test it for you.

-G


Top
 Profile  
 
 Post subject:
PostPosted: Thu Aug 19, 2004 10:46 am 
Newbie

Joined: Thu Aug 19, 2004 7:57 am
Posts: 14
Brannor McThife wrote:
Ok, understood.

Without writing out some code to test it, I'd go with the .delete(proposal) accessing the customer object as well, and as such causing the exception when you call the .delete(customer). Try deleting the customer first (might not work because of the unidirectional constraint).

If not, I'll try write some code to test it for you.

-G


I've tried that, but if you think about the order, the proposal needs to go first, because it needs the customer. Once the proposal is gone, only then do I want the ability to delete the customer.

_________________
Andy Czerwonka


Top
 Profile  
 
 Post subject: Found something....
PostPosted: Sun Aug 22, 2004 8:51 am 
Newbie

Joined: Thu Aug 19, 2004 7:57 am
Posts: 14
Given the following code...

Code:
public class SolutionTest extends TestCase
{
    public void testCreateSolutionWithProposedProductOne_Ok() throws Exception
    {
        // execute
        PersistenceManager.beginTransaction();
        Product product = new Product("Baseload");
        Customer customer = new Customer("customer id", "customer name");
        Site site = new Site(customer, "00042543544");
        Set sites = new HashSet();
        sites.add(site);
        Proposal proposal = new Proposal(customer, Calendar.getInstance(), Calendar.getInstance());
        Solution solution = new Solution(proposal, sites);
        ProposedProduct proposedProduct = new ProposedProduct(product, 5.99f, 333.33f, 1);
        solution.addProposedProduct(proposedProduct);
       
        PersistenceManager.saveOrUpdate(product);
        PersistenceManager.saveOrUpdate(customer);
        PersistenceManager.saveOrUpdate(proposal);
        PersistenceManager.commitTransaction();
       
        // validate
        Site found = SiteHome.getInstance().findByOid(site.getOid());
        assertNotNull("The found site is not null", found);
        assertEquals(site, found);

        // cleanup
        PersistenceManager.beginTransaction();
        PersistenceManager.delete(proposal);
        PersistenceManager.delete(customer);
        PersistenceManager.delete(product);
        PersistenceManager.commitTransaction();
    }



Now, if I remove the "validate" section, then the test works. When I find a site, the site references a customer, i.e. found.getCustomer(), which is the same customer. Also, if the do a delete on found.getCustomer() versus just customer, the test also works. The found object is in a new session, because when I commit, I close the session. Clearly, it's something within the two sessions. I do want to close the session after the commit, because this is a J2EE app and the commit will happen at the facade level. I'm thinking I need to reattch somehow.... anyone have a strategy for that that they've used?

_________________
Andy Czerwonka


Top
 Profile  
 
 Post subject: Tried this...
PostPosted: Sun Aug 22, 2004 9:36 am 
Newbie

Joined: Thu Aug 19, 2004 7:57 am
Posts: 14
Code:
public static void delete(Persistable persistable) throws HibernateException
    {
        if (!(currentSession().contains(persistable)))
            currentSession().load(persistable.getClass(), persistable.getOid());
        currentSession().delete(persistable);
    }


I thought I'd try and load the object into the current session when it's not there. Nope... still doesn't work. I'm guessing that the 'other' session still has it in it's cache somewhere, and that what it's still throwing the exception. Seem's like I need to somehow detach the object from the old session. Hmnnn.....

_________________
Andy Czerwonka


Top
 Profile  
 
 Post subject: Re: Found something....
PostPosted: Tue Sep 21, 2004 6:16 am 
Newbie

Joined: Tue Sep 21, 2004 5:35 am
Posts: 3
Hi Andy,

I have the same problem you described in you post.

Did you find a solution?

cheers
Pasquale D'Erasmo



czerwonka wrote:
Given the following code...

Code:
public class SolutionTest extends TestCase
{
    public void testCreateSolutionWithProposedProductOne_Ok() throws Exception
    {
        // execute
        PersistenceManager.beginTransaction();
        Product product = new Product("Baseload");
        Customer customer = new Customer("customer id", "customer name");
        Site site = new Site(customer, "00042543544");
        Set sites = new HashSet();
        sites.add(site);
        Proposal proposal = new Proposal(customer, Calendar.getInstance(), Calendar.getInstance());
        Solution solution = new Solution(proposal, sites);
        ProposedProduct proposedProduct = new ProposedProduct(product, 5.99f, 333.33f, 1);
        solution.addProposedProduct(proposedProduct);
       
        PersistenceManager.saveOrUpdate(product);
        PersistenceManager.saveOrUpdate(customer);
        PersistenceManager.saveOrUpdate(proposal);
        PersistenceManager.commitTransaction();
       
        // validate
        Site found = SiteHome.getInstance().findByOid(site.getOid());
        assertNotNull("The found site is not null", found);
        assertEquals(site, found);

        // cleanup
        PersistenceManager.beginTransaction();
        PersistenceManager.delete(proposal);
        PersistenceManager.delete(customer);
        PersistenceManager.delete(product);
        PersistenceManager.commitTransaction();
    }



Now, if I remove the "validate" section, then the test works. When I find a site, the site references a customer, i.e. found.getCustomer(), which is the same customer. Also, if the do a delete on found.getCustomer() versus just customer, the test also works. The found object is in a new session, because when I commit, I close the session. Clearly, it's something within the two sessions. I do want to close the session after the commit, because this is a J2EE app and the commit will happen at the facade level. I'm thinking I need to reattch somehow.... anyone have a strategy for that that they've used?


Top
 Profile  
 
 Post subject: net.sf.hibernate.NonUniqueObjectException: a different objec
PostPosted: Wed Sep 13, 2006 6:19 pm 
Newbie

Joined: Fri Aug 05, 2005 3:42 pm
Posts: 12
net.sf.hibernate.NonUniqueObjectException: a different object with the same identifier value was already associated with the session: 38094, of class: br.com.efat2.frw.beans.Usuario

Any ideis?


Top
 Profile  
 
 Post subject: A solution
PostPosted: Fri May 23, 2008 12:15 pm 
Newbie

Joined: Fri May 23, 2008 11:12 am
Posts: 8
I did something similar and thought I'd share what happened to me. My code looked something like this... (incorrect pseudo code but you can get the idea)
Code:
TestObject a = new TestObject();
session.save(a);
session.commitTransaction();
session.clear();
session.beginTransaction();
session.query("TestObject");
session.delete(a);
session.commitTransaction();


What happened to me was that after I called clear my object a was no longer associated with the session. When I preformed the query it created a new instance of TestObject for this object and associated it with the session. Then when I tried to call delete it tried to reassocate the object "a" with the session but found that it already had an instance from the query call. Since reassociating a with the session would cause two objects to be associated with the same identifier it caused the uniqueness exception. To resolve the issue in my case, I had to set the variable a to the instance that I recieved from the query like so...
Code:
TestObject a = new TestObject();
session.save(a);
session.commitTransaction();
session.clear();
session.beginTransaction();
a = session.query("TestObject");
session.delete(a);
session.commitTransaction();


Disclaimer: this code doesn't work, it's just meant to give you an idea of what's going on :-)


Top
 Profile  
 
Display posts from previous:  Sort by  
Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 17 posts ]  Go to page 1, 2  Next

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.