-->
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.  [ 9 posts ] 
Author Message
 Post subject: Merge() without automatic inserting of a removed object
PostPosted: Fri Jan 18, 2008 7:29 am 
Regular
Regular

Joined: Thu Oct 13, 2005 4:19 am
Posts: 98
I have a detached instance a, of which another instance b with the same id might already be loaded into the persistent context.

The state of a should be updated into the database, so I call
entityManager.merge(a);

If a still exists in the database, this performs well: I get an optimistic lock exception if a has been modified meanwhile.

If a has been deleted in the database meanwhile, I 'd like to get an exception too, but instead it insert it as a new record.
How can I get an exception instead?

Please note that I have no idea if there is a b with the same id or not already in the persistent context, so I can't check if b throws a optimistic lock exception.

Thanks for any and all help :)

_________________
http://www.ohloh.net/accounts/ge0ffrey


Top
 Profile  
 
 Post subject:
PostPosted: Fri Jan 18, 2008 8:59 am 
Expert
Expert

Joined: Thu Jul 05, 2007 9:38 am
Posts: 287
Just load the object by id. You'll get an exception or a null result depending on the method used.

_________________
Please rate useful posts.


Schauderhaft: Softwaredevelopment, Projectmanagement, Qualitymanagement and all things "schauderhaft"


Top
 Profile  
 
 Post subject:
PostPosted: Mon Jan 21, 2008 4:27 am 
Regular
Regular

Joined: Thu Oct 13, 2005 4:19 am
Posts: 98
Thanks, that works :)

But won't that hurt my performance?
I iterate through a list of P's, on which I load and merge continually, so I get a select-update-select-update-... pattern,
while I'd like to get:

update/delete ... where p.id = :id and p.version = version
If that changes 0 records it should trow an optimistic locking exception.
Notice I never want merge to insert something.

_________________
http://www.ohloh.net/accounts/ge0ffrey


Top
 Profile  
 
 Post subject:
PostPosted: Tue Jan 22, 2008 3:39 pm 
Expert
Expert

Joined: Thu Jul 05, 2007 9:38 am
Posts: 287
Ok, so how about this;


check with contains(), if the object is contained in the session.

If so do a merge(), else do an update().

I have not tried this, but I'd say it might work.

_________________
Please rate useful posts.


Schauderhaft: Softwaredevelopment, Projectmanagement, Qualitymanagement and all things "schauderhaft"


Top
 Profile  
 
 Post subject:
PostPosted: Tue Feb 05, 2008 8:44 am 
Regular
Regular

Joined: Thu Oct 13, 2005 4:19 am
Posts: 98
That doesn't work, because contains() returns false, even if a persistent instance with the same id is already in the cache.
That means that it still crashes once you run update because there is already a persistence instance with the same id in the cache.

_________________
http://www.ohloh.net/accounts/ge0ffrey


Top
 Profile  
 
 Post subject:
PostPosted: Fri Feb 08, 2008 4:39 am 
Expert
Expert

Joined: Thu Jul 05, 2007 9:38 am
Posts: 287
Hmm I don't understand the problem with the cache (I asume you are referring to the second level cache?)

Can you post some example code and the exception you get?

_________________
Please rate useful posts.


Schauderhaft: Softwaredevelopment, Projectmanagement, Qualitymanagement and all things "schauderhaft"


Top
 Profile  
 
 Post subject:
PostPosted: Fri Feb 08, 2008 4:42 am 
Expert
Expert

Joined: Thu Jul 05, 2007 9:38 am
Posts: 287
Hmm I don't understand the problem with the cache (I asume you are referring to the second level cache?)

Can you post some example code and the exception you get?

_________________
Please rate useful posts.


Schauderhaft: Softwaredevelopment, Projectmanagement, Qualitymanagement and all things "schauderhaft"


Top
 Profile  
 
 Post subject:
PostPosted: Wed Feb 13, 2008 4:01 am 
Regular
Regular

Joined: Thu Oct 13, 2005 4:19 am
Posts: 98
Actually I mean the first level cache.

Try something like this:

P detached = em.get(P.class, 101);
em.clear(); // detach it
detached.setDescription("dirty");

em.get(P.class, 101); // Load another instance with the same id in first level cache
if (em.constains(detached)) { // returns false
// this code isn't executed
}
em.getDelegate().update(detached); // throws exception because another instance with the same id is already in the first level cache.



Note I don't want to do em.clear(), because that causes havoc when I am building graph tree.

_________________
http://www.ohloh.net/accounts/ge0ffrey


Top
 Profile  
 
 Post subject:
PostPosted: Fri Feb 15, 2008 5:55 am 
Expert
Expert

Joined: Thu Jul 05, 2007 9:38 am
Posts: 287
Ok, now I get it.

I don't know about the entitymanager, but I guess you can get the underlying Hibernate session.

now try this:

Code:
session.getStatistics().getEntityKeys().contains(detached.getId());



This assumes, that getId() returns the id of your detached object.

You might have to activate statistics first, and I don't know what that does to your performance ...

If this doesn't work you could still try to hack your way in the Session private fields and methods ... after all they have to have the Ids somewhere ...

_________________
Please rate useful posts.


Schauderhaft: Softwaredevelopment, Projectmanagement, Qualitymanagement and all things "schauderhaft"


Top
 Profile  
 
Display posts from previous:  Sort by  
Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 9 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:
cron
© Copyright 2014, Red Hat Inc. All rights reserved. JBoss and Hibernate are registered trademarks and servicemarks of Red Hat, Inc.