-->
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.  [ 11 posts ] 
Author Message
 Post subject: Another object was associated with this id: on Orion only
PostPosted: Thu Oct 16, 2003 12:34 pm 
Regular
Regular

Joined: Mon Sep 08, 2003 10:05 am
Posts: 50
Location: Dublin, Ireland
I have a piece of code that works fine on JBoss 3.2.2, but fails on Orion 2.0.2, with the following error:

Code:
Another object was associated with this id (the object with the given id was already loaded): [com.BLAH.core.entity.NextId#3]


Now I know that this is normally because there are 2 different objects loaded, both with the same id.. but the thing is, I get the item back from a collection (via Session.find() ), I never make any copies of it.. I simply grab the object from the collection using the following:

Code:
Iterator iter  = nextIdCollection.iterator ();
nextId = (NextId) iter.next ();


(Note that I used to use "nextIdCollection.toArray()" to get the object, but this seems to return a copy of the object, rather than the object itself)

I then update a (non-id) field on nextId, and update it, which is when I get the Exception.

Is there any possibility that the call to "iter.next ();" is returning a different object (ie, a clone) to the one in the collection?? This is the only way I can explain how the error is occurring..

Am I missing anything?

Does anyone have an alternative explanation?

Why would this behave fine on JBoss 3.2.2, but not Orion 2.0.2???


Top
 Profile  
 
 Post subject: Re: Another object was associated with this id: on Orion onl
PostPosted: Fri Oct 17, 2003 2:31 pm 
Regular
Regular

Joined: Tue Sep 16, 2003 11:35 am
Posts: 93
Location: San Francisco, CA
themax wrote:
I then update a (non-id) field on nextId, and update it, which is when I get the Exception.


Is this what the code looks like more or less?
Code:
Entity e = session.load(Entity.class, id);
Collection ids = e.getNextIds();
for (Iterator i = ids.iterator; i.hasNext(); ) {
    NextId nextId = (NextId) i.next();
    nextId.setField(value);
    session.update(nextId);  // exception thrown
}


If so ... I'm not sure what you are trying to accomplish with the statement that throws the exception. My understanding is that Session.update() will update the instance you pass to it with the data actually in the database; it is not a "commit" action to write the changes you made to the java instance to the database, rather the opposite. Committing changes to the database happens when you flush/close the session.

Session.update() will try to make the java instance that you send to it the java instance associated with that {session,class,key} tuple, of which there can only be one. I suspect that the reason you are getting errors on one app server and not another has something to do with the way that object proxies or object copying are handled so that somehow the iterator it returning copies of the original instance.


Top
 Profile  
 
 Post subject:
PostPosted: Mon Oct 20, 2003 4:03 am 
Regular
Regular

Joined: Mon Sep 08, 2003 10:05 am
Posts: 50
Location: Dublin, Ireland
I think maybe our understanding of what Session.update () does is a little different... My understanding is that it will update the database with the data from the instance passed to the update method... in which case, the only way I have of getting the data back to the database is by calling the update. I need to do the update straight away because we're dealing id generation, to ensure that
    1) the id I reserved is not re-used
    2) so that the id tables don't get locked up, which would be a nightmare


That aside, my code is a little different from what u have there (I'm using a find, as mentioned earlier, rather than a load), but both would be quite similar in their canonical form.

Some more detail I found late on Friday: the address of "nextId" (what I see when I println it, given I haven't coded a "toString() method on it) changes *only* when I pass it to the update method on my session bean persistence.update(), so I guess that its a Serialisation issue as the nextId object is passed from one Session Bean to another.. I can test this by putting the update method in the same bean where its called from, and if that works, I know where the issue lies.. now whether that defines a bug, or is prescribed behaviour is another question.

I tested the same thing in JBoss, and the address does NOt change at that point, so maybe JBoss knows that both beans are in the same JVM, and hence does not need to (or attempt to) serialise the nextId object when it is passed to the other session beans method.


Top
 Profile  
 
 Post subject:
PostPosted: Mon Oct 20, 2003 5:12 am 
Regular
Regular

Joined: Mon Sep 08, 2003 10:05 am
Posts: 50
Location: Dublin, Ireland
If the update is done from within the same Session Bean (not calling an update method on a different Session Bean, which goes on to call the Session.update(xxx)), then the code works on Orion 2.0.2. (It worked on JBoss anyway)

What I learned is that the following error can have more causes than the FAQ might suggest.

Code:
Another object was associated with this id (the object with the given id was already loaded)


Is there a Hibernate specific reason why this would be the case (something in the doc that I missed)??? Gavin??


Top
 Profile  
 
 Post subject:
PostPosted: Mon Oct 20, 2003 11:07 am 
Beginner
Beginner

Joined: Tue Aug 26, 2003 9:50 am
Posts: 34
Location: Weiden Opf. / Germany
cutie is absolutely right.

in your case there's no need for a session.update() since you just got the objects from the db anyway. you need a session.flush() or a transaction.commit().

the session.update() is only used to persist a transient object which is no longer connected to a session to the db.


Top
 Profile  
 
 Post subject:
PostPosted: Mon Oct 20, 2003 11:37 am 
Regular
Regular

Joined: Mon Sep 08, 2003 10:05 am
Posts: 50
Location: Dublin, Ireland
Ok, I've confirmed the bit about not requiring the update () in this instance because I've just loaded it from the session. Thats as per the doc (Chapter 6. Manipulating Persistent Data)

I already had both a flush and a commit in place, so that should all work, but this still doesn't answer my question: why is the error occurring??

I haven't seen any documentation that says it is NOT ok to do an update on an object loaded in the session.. it just says that u don't **need** to..

The fact that this works fine in JBoss (a number of versions) would support this suggestion.

Quote:
6.4. Updating objects saved or loaded in the current session
Persistent instances (ie. objects loaded, saved, created or queried by the Session) may be manipulated by the application and any changes to persistent state will be persisted when the Session is flushed (see "flushing" below). So the most straightforward way to update the state of an object is to load() it, and then manipulate it directly.

DomesticCat cat = (DomesticCat) sess.load( Cat.class, new Long(69) );
cat.setName("PK");
sess.flush(); //changes to cat are automatically detected and persisted


It still looks to me like something is broken (probably Orion) , or maybe not, and the Hibernate doc just needs to be a little more explicit about how this case should NOT be handled, as well as how it **can** be handled..

To digress slightly from the main discussion.. I'm curious to see if some other issue would have occurred if I had removed the "update", and just done the flush and commit (where the update was happening on a different Session Bean, in Orion 2.0.2).. I may well check that out, time permitting.


Top
 Profile  
 
 Post subject:
PostPosted: Mon Oct 20, 2003 11:49 am 
Hibernate Team
Hibernate Team

Joined: Tue Aug 26, 2003 12:50 pm
Posts: 5130
Location: Melbourne, Australia
You do understand that some appservers serialize objects when passing them as arguments between EJBs, right?


Top
 Profile  
 
 Post subject:
PostPosted: Mon Oct 20, 2003 12:08 pm 
Regular
Regular

Joined: Mon Sep 08, 2003 10:05 am
Posts: 50
Location: Dublin, Ireland
Yes.. Thats why I asked about Serialisation in my first response. Its also something I haven't seen mentioned in the HIbernate doc, so it seems like a fair enough question to throw to the group.

Quote:
so I guess that its a Serialisation issue as the nextId object is passed from one Session Bean to another..


The issue of whether the update was required or not was slightly off the point (even though it was a perfectly valid observation)...

What I'm wondering is whether the Serialise issue thats occurring is prescribed behaviour, or a bug... I am (and others are) sure to encounter similar situations in the future, and it would be good to know whether what we're doing in that situation *should* work, or *could* work..

Quote:
now whether that defines a bug, or is prescribed behaviour is another question.


Top
 Profile  
 
 Post subject:
PostPosted: Mon Oct 20, 2003 1:49 pm 
Hibernate Team
Hibernate Team

Joined: Tue Aug 26, 2003 12:50 pm
Posts: 5130
Location: Melbourne, Australia
I'm sorry, could you please explain to me how could this possibly be a bug??

On the first page of the Hibernate documentation, we explain that, in a particular session, x.getId().equals( y.getId() ) is ALWAYS equivalent to x==y. This is a fundamental property of Hibernate. If you attempt to violate this, the exception is thrown.

So yes, of course, Hibernate is behaving as specified. Right?


Top
 Profile  
 
 Post subject:
PostPosted: Tue Oct 21, 2003 4:18 am 
Regular
Regular

Joined: Mon Sep 08, 2003 10:05 am
Posts: 50
Location: Dublin, Ireland
I'm questioning whether the Serialization bug / prescribed behaviour is in Orion 2.0.2, not Hibernate... I appreciate thats slightly off topic, so consider the matter closed.. I'll look elsewhere for the answer to this one.


Top
 Profile  
 
 Post subject:
PostPosted: Fri Nov 07, 2003 6:09 am 
Regular
Regular

Joined: Mon Sep 08, 2003 10:05 am
Posts: 50
Location: Dublin, Ireland
In the course of doing something else, I found that the default behaviour in Orion is to clone arguments in EJB parameters, rather than passing by value, if possible. This explains both issues.. (My curent issue, and this issue)

The deployment descriptor option to change this (and the relevant XDoclet tag) is "copy-by-value".. this solved my current issue i was having with Orion parameters, and would solve this issue as well (if I hadn't already worked around it)

I hope this saves someone else some issues running Hibernate (or whatever) on Orion! [OT] Its faster than JBoss, and seems more stringent in certain areas as well. Possibly a better development environment.. [/OT]

Pay attention, here comes the science..

orion-ejb-jar.xml
...
Code:
<!-- Session Beans -->
      <session-deployment name="Persistence"
                          copy-by-value="false"
                           location="persistence/Persistence"
                          >

      </session-deployment>
...



Java Code containing XDoclet tag (to build the deployment descriptor as part of the Ant Build)

Code:
/**
* @ejb.bean
*    view-type = "remote"
*   name="Persistence"
*   type="Stateful"
*   description="session ejb to access hibernate service"
*   jndi-name="persistence/Persistence"
*   transaction-type="Bean"
* @ejb.util          generate="physical"
* @ejb.permission    unchecked="true"
*
* @orion.bean
*  copy-by-value = "false"
*/
public class PersistenceBean extends BaseSessionBean
...


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