-->
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.  [ 1 post ] 
Author Message
 Post subject: Find or create within existing transaction
PostPosted: Wed Feb 16, 2011 8:12 pm 
Newbie

Joined: Wed Feb 16, 2011 7:43 pm
Posts: 1
I need to write a method which can find or create an object based on a unique but non-primary key.

As an example say I have a Person class as defined below:
Code:
public class Person {
   @Id
   @GeneratedValue(strategy = IDENTITY)
   private int id;
   
   @NaturalId
   @Column
   private String ssn;

   @Column
   private String name;
   
   ... //other fields and methods
}


I would like to be able to implement a method findOrCreate(String ssn) which obeys the following contract:

  • If a Person already exists in the db with the provided SSN, return that persistent object.
  • If no Person exists with the given SSN, create a new Person object with the given SSN (and default values for other fields), save the object and return it.
  • If two separate processes running on different machines both enter this method at the same time passing the same SSN, one of them should "win" and execute the save/insert while the other fetches the instance created by the "winning" process.
  • This method should be able to participate in an existing transaction where other inserts/updates/selects may happen before or after it completes. In other words it should never fail/cause a transaction rollback (we can assume no other processes will be deleting Person objects while this method executes.)


My initial thoughts for an algorithm like this would be the following:

1. Create the new Person object and attempt to save it.
2. If the save is successful, return the object.
3. If the save is unsuccessful (due to a violation of the unique constraint on the SSN column), fetch the Person from the db based on the SSN which is now guaranteed to return exactly one result.[/list]

The problem with this is that based on my admittedly shallow understanding of Hibernate, I can't try to save something and then recover from the error if a constraint is violated (at least not within the same transaction.)

Is there a way to make the merge() method do what I want? I see 2 problems with merge(): 1) If the Person already existed in the DB all the other fields besides SSN would be overwritten with the default values, 2) I'm not sure that the semantics of merge() make it acceptable for a distributed environment where multiple processes could be trying to merge the same object at the same time.

Please let me know if there is a good solution to this problem while still leveraging the Hibernate framework.


Top
 Profile  
 
Display posts from previous:  Sort by  
Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 1 post ] 

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.