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

06-08-18 lyojbuilder

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) 
<p>

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> 
<p>

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

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

<p>

这里如果换成 save就没问题! :?

这个方法用的有问题吗?

banq
2006-08-21 10:03

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

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

lyojbuilder
2006-08-26 08:13

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