-->
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.  [ 4 posts ] 
Author Message
 Post subject: How to insert a record or update it if it already exists?
PostPosted: Mon Dec 29, 2008 10:02 am 
Newbie

Joined: Mon Dec 29, 2008 9:48 am
Posts: 6
Hi.
I need to update a record in a table. The problem is that the record may not exist yet.
Since I'm working in a multi-threaded environment, I want to have a single command create it only if it doesn't exist yet, to prevent two different threads from creating it simultaneously.

How is it possible (using HQL or hibernate session methods) to update a record or create it if it doesn't exist yet?
If it's not possible, is there any suggested workaround (I'm working with multiple database implementations, so I'd rather not use proprietary SQL)?

Thanks,
Oz


Top
 Profile  
 
 Post subject:
PostPosted: Mon Dec 29, 2008 11:00 pm 
Hibernate Team
Hibernate Team

Joined: Tue Aug 26, 2003 7:19 pm
Posts: 2364
Location: Brisbane, Australia
Have you checked the documentation?

Assuming your using the session object you have a method that provides this service, e.g.,

session.saveOrUpdate(Object );


Top
 Profile  
 
 Post subject:
PostPosted: Tue Dec 30, 2008 3:27 am 
Newbie

Joined: Mon Dec 29, 2008 9:48 am
Posts: 6
david wrote:
Have you checked the documentation?

Assuming your using the session object you have a method that provides this service, e.g.,

session.saveOrUpdate(Object );



Thanks David. I did see this method but for some reason didn't think to use it because the fields I used didn't have a unique constraint, so I figured it would just create another record with the same values.
Now that I think about it, I can't remember why I wanted to avoid unique constraints, so I'll try and do it this way.
Thanks a lot,
Oz


Top
 Profile  
 
 Post subject: Re:
PostPosted: Tue Sep 01, 2009 8:32 am 
Beginner
Beginner

Joined: Tue Nov 06, 2007 5:13 am
Posts: 28
david wrote:
Have you checked the documentation?

Assuming your using the session object you have a method that provides this service, e.g.,

session.saveOrUpdate(Object );


This does not solve the problem described.
In fact, it will not even work in one single thread, when you try to saveOrUpdate() the same data twice:
Code:
Entity createNewEntity() {
  Entity result = new Entity();
  result.setUniqueField("A");
  return result;
}

testMethod() {
  session.saveOrUpdate(createNewEntity());
  session.flush();
  session.clear();
  session.saveOrUpdate(createNewEntity()); // UNIQUE CONSTRAINT VIOLATION
}


and I cannot see anything in the documentation that states, that it should: But please correct me, if I missed something.

So how can this be solved?
There are some things that come to my mind, but I don't like any of them...

  • transaction-isolationlevel repeadable read (or synchronized)
    If the function, that inserts/updates the record uses the correct transaction-isolationlevel, it should work.
    • do all databases support this synchronization level? - What if not?
    • this isolation-level will lock the complete table while it's used, so there may be a better alternative
  • 2nd session with the same transaction (JDBC-connection)
    open a 2nd session that works with the same transaction. try to insert the record - if a constraint-violation occurs, update the existing record in the original session
    • this seems awkward
    • I don't know how to open a second session with the same connection in Spring
  • simply catch the ConstraintViolationException and then update the existing record
  • single point to write those files
    the service methods don't write these entities, but only pass them to one specific thread, that will persist those entities in a separate session (and transaction)
    • 2 different transactions and all the common problems that arise
  • aggregation task
    the service methods write these entities directly to a table A, that does not have the unique-constraint.
    an aggregation task will, select all entries of one type, write the newest to another table B that has the unique constraint and then delete the original entries
    • this is a lot of work
    • table B will not always show the most-recent data

any guidance/hints/comments welcome


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