-->
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.  [ 15 posts ] 
Author Message
 Post subject: saveOrUpdate
PostPosted: Fri Nov 05, 2010 1:41 pm 
Newbie

Joined: Fri Nov 05, 2010 1:36 pm
Posts: 11
How come saveOrUpdate does not work for the save part but does work for the update?
If I use:

session.saveOrUpdate(item);

it does not work for a save but does for an update.

If I change to:

session.save(item);

the save is done correctly.

The message says something about the number of updates(0) does not match the expected number of updates(1) or something like that.

When I then try to update the row I just saved, the

session.saveOrUpdate(item);

works just fine.


Top
 Profile  
 
 Post subject: Re: saveOrUpdate
PostPosted: Sat Nov 06, 2010 12:21 pm 
Senior
Senior

Joined: Fri Oct 08, 2010 8:44 am
Posts: 130
Post exact message, not "something like that" :)


Top
 Profile  
 
 Post subject: Re: saveOrUpdate
PostPosted: Mon Nov 08, 2010 12:44 pm 
Newbie

Joined: Fri Nov 05, 2010 1:36 pm
Posts: 11
r wrote:
Post exact message, not "something like that" :)


OK, here it is:



Hibernate: update item set name=?, description=? where id=?
1422 [main] ERROR org.hibernate.event.def.AbstractFlushingEventListener - Could not synchronize database state with session
org.hibernate.StaleStateException: Batch update returned unexpected row count from update [0]; actual row count: 0; expected: 1
at org.hibernate.jdbc.Expectations$BasicExpectation.checkBatched(Expectations.java:85)
at org.hibernate.jdbc.Expectations$BasicExpectation.verifyOutcome(Expectations.java:70)
at org.hibernate.jdbc.NonBatchingBatcher.addToBatch(NonBatchingBatcher.java:47)
at org.hibernate.persister.entity.AbstractEntityPersister.update(AbstractEntityPersister.java:2431)
at org.hibernate.persister.entity.AbstractEntityPersister.updateOrInsert(AbstractEntityPersister.java:2335)
at org.hibernate.persister.entity.AbstractEntityPersister.update(AbstractEntityPersister.java:2635)
at org.hibernate.action.EntityUpdateAction.execute(EntityUpdateAction.java:115)
at org.hibernate.engine.ActionQueue.execute(ActionQueue.java:279)
at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:263)
at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:168)
at org.hibernate.event.def.AbstractFlushingEventListener.performExecutions(AbstractFlushingEventListener.java:321)
at org.hibernate.event.def.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:50)
at org.hibernate.impl.SessionImpl.flush(SessionImpl.java:1027)
at org.hibernate.impl.SessionImpl.managedFlush(SessionImpl.java:365)
at org.hibernate.transaction.JDBCTransaction.commit(JDBCTransaction.java:137)
at hibernate.BatchAddOrUpdate.main(BatchAddOrUpdate.java:61)
Hibernate ExceptionBatch update returned unexpected row count from update [0]; actual row count: 0; expected: 1
Exception in thread "main" java.lang.RuntimeException: org.hibernate.StaleStateException: Batch update returned unexpected row count from update [0]; actual row count: 0; expected: 1
at hibernate.BatchAddOrUpdate.main(BatchAddOrUpdate.java:64)
Caused by: org.hibernate.StaleStateException: Batch update returned unexpected row count from update [0]; actual row count: 0; expected: 1
at org.hibernate.jdbc.Expectations$BasicExpectation.checkBatched(Expectations.java:85)
at org.hibernate.jdbc.Expectations$BasicExpectation.verifyOutcome(Expectations.java:70)
at org.hibernate.jdbc.NonBatchingBatcher.addToBatch(NonBatchingBatcher.java:47)
at org.hibernate.persister.entity.AbstractEntityPersister.update(AbstractEntityPersister.java:2431)
at org.hibernate.persister.entity.AbstractEntityPersister.updateOrInsert(AbstractEntityPersister.java:2335)
at org.hibernate.persister.entity.AbstractEntityPersister.update(AbstractEntityPersister.java:2635)
at org.hibernate.action.EntityUpdateAction.execute(EntityUpdateAction.java:115)
at org.hibernate.engine.ActionQueue.execute(ActionQueue.java:279)
at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:263)
at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:168)
at org.hibernate.event.def.AbstractFlushingEventListener.performExecutions(AbstractFlushingEventListener.java:321)
at org.hibernate.event.def.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:50)
at org.hibernate.impl.SessionImpl.flush(SessionImpl.java:1027)
at org.hibernate.impl.SessionImpl.managedFlush(SessionImpl.java:365)
at org.hibernate.transaction.JDBCTransaction.commit(JDBCTransaction.java:137)
at hibernate.BatchAddOrUpdate.main(BatchAddOrUpdate.java:61)


Here is the program code:


package hibernate;

import org.hibernate.HibernateException;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.cfg.Configuration;

public class BatchAddOrUpdate {

public static void main(String[] args) {

Configuration cfg = new Configuration();

// cfg.addResource("hibernate/Hibernate.cfg.xml");
cfg.addResource("hibernate/item.hbm.xml");
cfg.setProperties(System.getProperties());
// cfg.setProperty("connection.driver_class",
// "oracle.jdbc.driver.OracleDriver");
// cfg.setProperty("connection.url",
// "jdbc:oracle:thin:@athlon3200:1521:orcl");
// cfg.setProperty("connection.username", "SCOTT");
// cfg.setProperty("connection.password", "tiger");
cfg.setProperty("hibernate.dialect",
"org.hibernate.dialect.Oracle9iDialect");

// System.out.println("cfg.getProperties().getProperty('user.country') =
// " + cfg.getProperties().getProperty("user.country"));
// System.out.println("cfg.getProperties().getProperty('connection.driver_class')
// = " + cfg.getProperties().getProperty("connection.driver_class"));
// System.out.println("cfg.getProperties().getProperty('connection.url')
// = " + cfg.getProperties().getProperty("connection.url"));
// System.out.println("cfg.getProperties().getProperty('connection.username')
// = " + cfg.getProperties().getProperty("connection.username"));
// System.out.println("cfg.getProperties().getProperty('connection.password')
// = " + cfg.getProperties().getProperty("connection.password"));
System.out
.println("cfg.getProperties().getProperty('hibernate.dialect') = "
+ cfg.getProperties().getProperty("hibernate.dialect"));

SessionFactory sessions = cfg.buildSessionFactory();

Item item = new Item();

item.setId(8L);
item.setDescription("Test Item #8a");
item.setName("XXXXX #8a");

Session session = ConnectionFactory.getInstance().getSession();

try {
Transaction tx = session.beginTransaction();

session.saveOrUpdate(item);
// session.save(item);
// session.update(item);
// item.setDescription("set after");
// item.setName("set after");
// session.flush();

tx.commit();
} catch (HibernateException e) {
System.err.println("Hibernate Exception" + e.getMessage());
throw new RuntimeException(e);
}
/*
* Regardless of whether the above processing resulted in an Exception
* or proceeded normally, we want to close the Hibernate session. When
* closing the session, we must allow for the possibility of a Hibernate
* Exception.
*
*/
finally {
if (session != null) {
try {

session.close();
} catch (HibernateException e) {
System.err.println("Hibernate Exception" + e.getMessage());
throw new RuntimeException(e);
}

}
}

}
}


Top
 Profile  
 
 Post subject: Re: saveOrUpdate
PostPosted: Mon Nov 08, 2010 4:04 pm 
Senior
Senior

Joined: Fri Oct 08, 2010 8:44 am
Posts: 130
What generator type have you set for your ID field?


Top
 Profile  
 
 Post subject: Re: saveOrUpdate
PostPosted: Mon Nov 08, 2010 4:14 pm 
Newbie

Joined: Fri Nov 05, 2010 1:36 pm
Posts: 11
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">

<hibernate-mapping>
<class name="hibernate.Item" table="item" >
<id name="id" column="id" type="java.lang.Long" unsaved-value="0">
<generator class="assigned"/>
</id>
<property name="name" column="name" type="java.lang.String" />
<property name="description" column="description" type="java.lang.String" />
</class>
</hibernate-mapping>


Top
 Profile  
 
 Post subject: Re: saveOrUpdate
PostPosted: Mon Nov 08, 2010 5:57 pm 
Senior
Senior

Joined: Fri Oct 08, 2010 8:44 am
Posts: 130
Your mapping means that you have to set value of your ID field to zero before calling "save". Otherwise it will give exception you seen. So you have to choices: (1) always set ID field to 0 before calling "save", (2) remove "unsaved-value" attribute from your generator definition.


Top
 Profile  
 
 Post subject: Re: saveOrUpdate
PostPosted: Mon Nov 08, 2010 6:28 pm 
Newbie

Joined: Fri Nov 05, 2010 1:36 pm
Posts: 11
r wrote:
Your mapping means that you have to set value of your ID field to zero before calling "save". Otherwise it will give exception you seen. So you have to choices: (1) always set ID field to 0 before calling "save", (2) remove "unsaved-value" attribute from your generator definition.



But it saves fine when I use save. It just has a problem saving when I use saveOrUpdate.


Top
 Profile  
 
 Post subject: Re: saveOrUpdate
PostPosted: Tue Nov 09, 2010 4:45 am 
Senior
Senior

Joined: Fri Oct 08, 2010 8:44 am
Posts: 130
r wrote:
Your mapping means that you have to set value of your ID field to zero before calling "save". Otherwise it will give exception you seen. So you have to choices: (1) always set ID field to 0 before calling "save", (2) remove "unsaved-value" attribute from your generator definition.


No talking comrade, just do what I said to you! :)

The only way Hibernate is able determine if particular entity needed to be SAVED or UPDATED in "saveOrUpdate" method is by checking value of "id" field. If it is equal to "unsaved-value" it tries to save it, if it is not equal it tries to update it. That why you get the error only when you call "saveOrUpdate".


Top
 Profile  
 
 Post subject: Re: saveOrUpdate
PostPosted: Tue Nov 09, 2010 10:03 am 
Newbie

Joined: Fri Nov 05, 2010 1:36 pm
Posts: 11
r wrote:
r wrote:
Your mapping means that you have to set value of your ID field to zero before calling "save". Otherwise it will give exception you seen. So you have to choices: (1) always set ID field to 0 before calling "save", (2) remove "unsaved-value" attribute from your generator definition.


No talking comrade, just do what I said to you! :)

The only way Hibernate is able determine if particular entity needed to be SAVED or UPDATED in "saveOrUpdate" method is by checking value of "id" field. If it is equal to "unsaved-value" it tries to save it, if it is not equal it tries to update it. That why you get the error only when you call "saveOrUpdate".



OK thanks, I will try it a little later.


Top
 Profile  
 
 Post subject: Re: saveOrUpdate
PostPosted: Tue Nov 09, 2010 10:08 pm 
Newbie

Joined: Fri Nov 05, 2010 1:36 pm
Posts: 11
r wrote:
r wrote:
Your mapping means that you have to set value of your ID field to zero before calling "save". Otherwise it will give exception you seen. So you have to choices: (1) always set ID field to 0 before calling "save", (2) remove "unsaved-value" attribute from your generator definition.


No talking comrade, just do what I said to you! :)

The only way Hibernate is able determine if particular entity needed to be SAVED or UPDATED in "saveOrUpdate" method is by checking value of "id" field. If it is equal to "unsaved-value" it tries to save it, if it is not equal it tries to update it. That why you get the error only when you call "saveOrUpdate".


Just a question. Why do I need this method then? It would seem that I should know myself what I set that field to so I should know myself whether to issue a save() or an update().
I thought that this method was to check the database with one of the two methods and depending on whether or not there was a returned exception, call the other.


Top
 Profile  
 
 Post subject: Re: saveOrUpdate
PostPosted: Wed Nov 10, 2010 7:13 am 
Senior
Senior

Joined: Fri Oct 08, 2010 8:44 am
Posts: 130
TimBee2 wrote:
Just a question. Why do I need this method then? It would seem that I should know myself what I set that field to so I should know myself whether to issue a save() or an update().
I thought that this method was to check the database with one of the two methods and depending on whether or not there was a returned exception, call the other.


You need this in case you did not specify "unsaved-value" attribute. That why I asked you to remove it in the first place. Did you read that part? ;)

Here is part of Hibernate manual you missed:

Quote:
5.1.4.5. Assigned identifiers

If you want the application to assign identifiers, as opposed to having Hibernate generate them, you can use the assigned generator. This special generator uses the identifier value already assigned to the object's identifier property. The generator is used when the primary key is a natural key instead of a surrogate key. This is the default behavior if you do not specify a <generator> element.

The assigned generator makes Hibernate use unsaved-value="undefined". This forces Hibernate to go to the database to determine if an instance is transient or detached, unless there is a version or timestamp property, or you define Interceptor.isUnsaved().


Top
 Profile  
 
 Post subject: Re: saveOrUpdate
PostPosted: Wed Nov 10, 2010 11:41 am 
Newbie

Joined: Fri Nov 05, 2010 1:36 pm
Posts: 11
r wrote:
TimBee2 wrote:
Just a question. Why do I need this method then? It would seem that I should know myself what I set that field to so I should know myself whether to issue a save() or an update().
I thought that this method was to check the database with one of the two methods and depending on whether or not there was a returned exception, call the other.


You need this in case you did not specify "unsaved-value" attribute. That why I asked you to remove it in the first place. Did you read that part? ;)

Here is part of Hibernate manual you missed:

Quote:
5.1.4.5. Assigned identifiers

If you want the application to assign identifiers, as opposed to having Hibernate generate them, you can use the assigned generator. This special generator uses the identifier value already assigned to the object's identifier property. The generator is used when the primary key is a natural key instead of a surrogate key. This is the default behavior if you do not specify a <generator> element.

The assigned generator makes Hibernate use unsaved-value="undefined". This forces Hibernate to go to the database to determine if an instance is transient or detached, unless there is a version or timestamp property, or you define Interceptor.isUnsaved().



Just tested it and it works. Thanks. Not sure what good it is using the generator since you know ahead of time whether or not the row has that column as 0 or has been generated previously.


Top
 Profile  
 
 Post subject: Re: saveOrUpdate
PostPosted: Wed Nov 10, 2010 12:05 pm 
Senior
Senior

Joined: Fri Oct 08, 2010 8:44 am
Posts: 130
TimBee2 wrote:
Just tested it and it works. Thanks. Not sure what good it is using the generator since you know ahead of time whether or not the row has that column as 0 or has been generated previously.


I think you are not reading what I am writing to you, or I do not explain clearly enough :)

If you REMOVE "unsaved-value" attribute from your mapping Hibernate does SELECT and checks if record is already there. If it is there it does UPDATE, otherwise INSERT.

Is it clear?


Top
 Profile  
 
 Post subject: Re: saveOrUpdate
PostPosted: Wed Nov 10, 2010 12:26 pm 
Newbie

Joined: Fri Nov 05, 2010 1:36 pm
Posts: 11
r wrote:
TimBee2 wrote:
Just tested it and it works. Thanks. Not sure what good it is using the generator since you know ahead of time whether or not the row has that column as 0 or has been generated previously.


I think you are not reading what I am writing to you, or I do not explain clearly enough :)

If you REMOVE "unsaved-value" attribute from your mapping Hibernate does SELECT and checks if record is already there. If it is there it does UPDATE, otherwise INSERT.

Is it clear?


Yes. It works fine when I remove that.

But what is the reason for "unsaved-value"? If I leave that in and set the attribute to 0, it inserts it with a value of zero, it doesn't generate a new value. So when I try to update it, it says there is already a row with that value.
Is that because I have <generator class="assigned"/> which means I have to assign the value myself rather than have it automatically generated?


Top
 Profile  
 
 Post subject: Re: saveOrUpdate
PostPosted: Wed Nov 10, 2010 12:29 pm 
Senior
Senior

Joined: Fri Oct 08, 2010 8:44 am
Posts: 130
TimBee2 wrote:
Yes. It works fine when I remove that.

But what is the reason for "unsaved-value"? If I leave that in and set the attribute to 0, it inserts it with a value of zero, it doesn't generate a new value. So when I try to update it, it says there is already a row with that value.
Is that because I have <generator class="assigned"/> which means I have to assign the value myself rather than have it automatically generated?


Yes, exactly. You may want to use "sequence" generator class instead with your Oracle sequences if you want it to be generated automatically.


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