saveOrUpdate方法在hibernate3中和以前的不一致?

robbin 在一篇帖子里详细讲过 saveOrUpdate 方法的使用,前提把


unsaved-value="null"
设置好。 如果一个对象在数据库存在,就update他,否则就 save他,但是我在 hibernate3.1.3中使用报错:

2006-08-18 05:58:10 StandardWrapperValve[action]: Servlet.service() for servlet action threw exception
org.hibernate.StaleStateException: Batch update returned unexpected row count from update: 0 actual row count: 0 expected: 1
at org.hibernate.jdbc.BatchingBatcher.checkRowCount(BatchingBatcher.java:93)
at org.hibernate.jdbc.BatchingBatcher.checkRowCounts(BatchingBatcher.java:79)
at org.hibernate.jdbc.BatchingBatcher.doExecuteBatch(BatchingBatcher.java:58)
at org.hibernate.jdbc.AbstractBatcher.executeBatch(AbstractBatcher.java:195)
at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:235)
at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:140)
at org.hibernate.event.def.AbstractFlushingEventListener.performExecutions(AbstractFlushingEventListener.java:297)
at org.hibernate.event.def.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:27)
at org.hibernate.impl.SessionImpl.flush(SessionImpl.java:985)
at org.hibernate.impl.SessionImpl.managedFlush(SessionImpl.java:333)
at org.hibernate.transaction.JDBCTransaction.commit(JDBCTransaction.java:106)
at com.fangtoo.questbook.service.UserDaoImpl.saveObject(UserDaoImpl.java:111)
at com.fangtoo.questbook.action.RegUserAction.execute(RegUserAction.java:61)
at org.apache.struts.action.RequestProcessor.processActionPerform(RequestProcessor.java:431)
at org.apache.struts.action.RequestProcessor.process(RequestProcessor.java:236)
at org.apache.struts.action.ActionServlet.process(ActionServlet.java:1196)
at org.apache.struts.action.ActionServlet.doPost(ActionServlet.java:432)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:763)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:856)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:284)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:204)
at org.nanocontainer.nanowar.ServletRequestContainerFilter.doFilter(ServletRequestContainerFilter.java:44)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:233)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:204)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:256)
at org.apache.catalina.core.StandardValveContext.invokeNext(StandardValveContext.java:151)
at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:564)
at org.apache.catalina.core.StandardContextValve.invokeInternal(StandardContextValve.java:245)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:199)
at org.apache.catalina.core.StandardValveContext.invokeNext(StandardValveContext.java:151)
at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:564)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:195)
at org.apache.catalina.core.StandardValveContext.invokeNext(StandardValveContext.java:151)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:164)
at org.apache.catalina.core.StandardValveContext.invokeNext(StandardValveContext.java:149)
at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:564)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:156)
at org.apache.catalina.core.StandardValveContext.invokeNext(StandardValveContext.java:151)
at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:564)
at org.apache.catalina.core.ContainerBase.invoke(ContainerBase.java:972)
at org.apache.coyote.tomcat5.CoyoteAdapter.service(CoyoteAdapter.java:211)
at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:805)
at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.processConnection(Http11Protocol.java:696)
at org.apache.tomcat.util.net.TcpWorkerThread.runIt(PoolTcpEndpoint.java:605)
at org.apache.tomcat.util.threads.ThreadPool$ControlRunnable.run(ThreadPool.java:677)
at java.lang.Thread.run(Thread.java:534)

mapping:


<hibernate-mapping>
<class name="lyo.test.Userinfo" table="userinfo">
<id name=
"userinfoId" type="java.lang.Long" unsaved-value="null">
<column name=
"USERINFO_ID" />
<generator class=
"native" />
</id>
<property name=
"userinfoName" type="string">
<column name=
"USERINFO_NAME" length="20">
<comment></comment>
</column>
</property>
</hibernate-mapping>

保存时候的代码(Session可以正确得到)

Session s2=this.s; 
Transaction t=s2.beginTransaction();
s2.saveOrUpdate(objTransient);
t.commit();
return objTransient;


这里如果换成 save就没问题! :?
这个方法用的有问题吗?

不但要设置unsaved为空,而且你的Domain Model(Userinfo)的主键userinfoId不能为原始型。


你的问题是你使用了 generator class 设置主键id,Hibernate是根据主键设置unsaved的值来判断是insert还是update,因为你设置了id,所有Hibernate总是update,看看手册解决方式。

您是说必须使用 assign的方式分配id才可以? 我得pojo使用的是封装类java.lang.Long。