-->
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.  [ 7 posts ] 
Author Message
 Post subject: Best way to "update or insert"?
PostPosted: Wed Feb 24, 2010 4:55 pm 
Newbie

Joined: Wed Feb 24, 2010 3:43 pm
Posts: 4
I would like to persist my POJOs using Hibernate into a MySql database by first trying to "update", then "flush", then check the number of rows updated, then do an insert if that number was 0.
I chose the sequence above because my objects will be typically already present in the database, in which case I want to update them.

I realize I can do this with an HQL query, e.g.
int numRowsUpdated = session.createQuery("update Account a set ... a long list of fields ... where a.compositePkPart1=:compositePkPart1 and a.compositePkPart2=compositePkPart2")
.setString(....)
.... a long list of setters...
.setString("compositePkPart1 ", ...)
.setString("compositePkPart2", ...)
.executeUpdate();
if(numRowsUpdated==0) {
session.save(account);
}

Unfortunately my "Account" object is quite complex, has many attributes, has sub-classes (represented by "joined-subclass" in the hibernate mapping) with many attributes, so the code fragment above would look more like 500 lines of code (haven't written it yet).

So my question is:
Is there an easier way (shorter code) to do this?
I cannot use "session.update(account)", because it does not return the number of rows updated.
Maybe there is a way to write an HQL "update" query that is short and that can update all attributes of my object? e.g.
int numRowsUpdated = session.createQuery("update Account a set a=:a where a.compositePkPart1=:compositePkPart1 and a.compositePkPart2=compositePkPart2")
.setEntity(a, account)
.setString("compositePkPart1 ", ...)
.setString("compositePkPart2", ...)
.executeUpdate();
I tried this without success...

I appreciate your input.
Thank you,
-Ivan


Top
 Profile  
 
 Post subject: Re: Best way to "update or insert"?
PostPosted: Wed Feb 24, 2010 5:41 pm 
Newbie

Joined: Wed Feb 24, 2010 3:43 pm
Posts: 4
Me again:
I want to clarify that my "Account" has a composite primary key (composed of two string-s);
The related hibernate mapping for "Account is:
<composite-id mapped="true" >
<key-property name="compositePkPart1" column="compositePkPart1" type="string" />
<key-property name="compositePkPart2" column="compositePkPart2" type="string" />
</composite-id>
Before calling update, my Account-s already have the compositePkPart1 and compositePkPart2 populated (they do not come from a db. sequence).

I am reading about "versioning" in Hibernate - Perhaps with "versioning" I can instruct Hibernate to do an SQL update followed by insert just by calling session.save(account) ? How do I achieve this?

Thanks,
-Ivan


Top
 Profile  
 
 Post subject: Re: Best way to "update or insert"?
PostPosted: Wed Feb 24, 2010 5:58 pm 
Beginner
Beginner

Joined: Tue Aug 25, 2009 11:42 am
Posts: 49
Hibernate doesn't have many fancy batch updates and other batch processing. I guess it was not their goal to begin with.
Try using session.load() it can give u a lazy proxy (so that u don't have to incur the time consuming setting of all properties). Then set any property that u intend to update and save.


Top
 Profile  
 
 Post subject: Re: Best way to "update or insert"?
PostPosted: Wed Feb 24, 2010 7:04 pm 
Newbie

Joined: Wed Feb 24, 2010 3:43 pm
Posts: 4
Me again.
I came-up with the following approach which I can not get to work perfectly - see the code comments below:
try {
session.load(Account.class, account);
// Try to SQL update an existing record in the db. that has the same PK:
session.update(account);
session.flush();
} catch(org.hibernate.StaleStateException e) {
// The update() above didn't find any record. Do an SQL insert:
// Note: The call to save() below should generate only SQL insert statements.
// However, it generates also some update-s and delete-s - don't know why.
// What should I do to get it to generate only insert-s? Calling session.evict(account) does not help...
session.flush();
//}
}


Top
 Profile  
 
 Post subject: Re: Best way to "update or insert"?
PostPosted: Wed Feb 24, 2010 7:28 pm 
Expert
Expert

Joined: Wed Mar 03, 2004 6:35 am
Posts: 1240
Location: Lund, Sweden
It's not possible to rely on exceptions thrown by a session like this. Read http://docs.jboss.org/hibernate/stable/ ... exceptions

I suggest that you use session.merge(). It should give you the desired behavior. See http://docs.jboss.org/hibernate/stable/ ... veorupdate


Top
 Profile  
 
 Post subject: Re: Best way to "update or insert"?
PostPosted: Wed Feb 24, 2010 11:38 pm 
Newbie

Joined: Wed Feb 24, 2010 3:43 pm
Posts: 4
nordborg wrote:
I suggest that you use session.merge(). It should give you the desired behavior. See http://docs.jboss.org/hibernate/stable/ ... veorupdate


I tried "session.merge()", and it didn't work for me, as it generated many "select" sql statements, which I don't want.
I want to end-up with efficient SQL queries: the code should do an SQL update first, and only if that update returned 0 rows, it should do an SQL insert (I could write this code easily in JDBC). No "select" queries are needed.

Any other suggestion?

-Ivan


Top
 Profile  
 
 Post subject: Re: Best way to "update or insert"?
PostPosted: Wed Feb 24, 2010 11:41 pm 
Beginner
Beginner

Joined: Tue Aug 25, 2009 11:42 am
Posts: 49
session.load(Account.class,account)??

What are u trying to do?
What is "account"?
I was expecting something like
Account account = (Account) session.load(Account.class, acNo);

As for merge, it will create a new entity in the db if one doesn't exist otherwise update the existing one. But I thought the original question was how to only update selected properties without fully initializing an entity in case it existed.


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