问题描述
首先,数据库表是空的,在程序里调用saveOrUpdate方法,产生的sql语句却是 update user set user_name=?, real_name=?, password=?, sex=?, birthday=?, email=?, address=?, telephone=?, qq=?, authority=?, remarks=? where user_id=?这样当然会出错,明明数据库根本没有数据,为什么执行的是修改表结构CREATE TABLE USER( user_id INT PRIMARY KEY NOT NULL,//不是自增 user_name VARCHAR(30), real_name VARCHAR(20), PASSWORD VARCHAR(20), sex VARCHAR(3), birthday VARCHAR(30), email VARCHAR(40), address VARCHAR(50), telephone VARCHAR(20), qq VARCHAR(15), authority VARCHAR(50), remarks VARCHAR(50)配置入下xx.hbm.xml<hibernate-mapping> <class name="com.flex.model.User" table="user" > <id name="userId" type="java.lang.Integer"> <column name="user_id" /> <generator class="native"></generator> </id> <property name="userName" type="java.lang.String"> <column name="user_name" length="30" /> </property> <property name="realName" type="java.lang.String"> <column name="real_name" length="20" /> </property> <property name="password" type="java.lang.String"> <column name="password" length="20" /> </property> <property name="sex" type="java.lang.String"> <column name="sex" length="3" /> </property> <property name="birthday" type="java.lang.String"> <column name="birthday" length="30" /> </property> <property name="email" type="java.lang.String"> <column name="email" length="40" /> </property> <property name="address" type="java.lang.String"> <column name="address" length="50" /> </property> <property name="telephone" type="java.lang.String"> <column name="telephone" length="20" /> </property> <property name="qq" type="java.lang.String"> <column name="qq" length="15" /> </property> <property name="authority" type="java.lang.String"> <column name="authority" length="50" /> </property> <property name="remarks" type="java.lang.String"> <column name="remarks" length="50" /> </property> </class></hibernate-mapping>================================================调用方法源码 hibernate本身的org.springframework.orm.hibernate3.HibernateTemplate.saveOrUpdateAllpublic void saveOrUpdateAll(final Collection entities) throws DataAccessException {executeWithNativeSession(new HibernateCallback<Object>() {public Object doInHibernate(Session session) throws HibernateException {checkWriteOperationAllowed(session);for (Object entity : entities) {session.saveOrUpdate(entity);}return null;}});================================================错误日志22 11:31:28,668 [http-8080-2] ERROR org.hibernate.event.def.AbstractFlushingEventListener- Could not synchronize database state with sessionorg.hibernate.StaleStateException: Batch update returned unexpected row count from update: 0 actual row count: 0 expected: 1at org.hibernate.jdbc.BatchingBatcher.checkRowCount(BatchingBatcher.java:92)at org.hibernate.jdbc.BatchingBatcher.checkRowCounts(BatchingBatcher.java:78)at org.hibernate.jdbc.BatchingBatcher.doExecuteBatch(BatchingBatcher.java:57)at org.hibernate.jdbc.BatchingBatcher.addToBatch(BatchingBatcher.java:33)at org.hibernate.persister.entity.BasicEntityPersister.update(BasicEntityPersister.java:1982)at org.hibernate.persister.entity.BasicEntityPersister.updateOrInsert(BasicEntityPersister.java:1909)at org.hibernate.persister.entity.BasicEntityPersister.update(BasicEntityPersister.java:2149)at org.hibernate.action.EntityUpdateAction.execute(EntityUpdateAction.java:75)at org.hibernate.engine.ActionQueue.execute(ActionQueue.java:239)at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:223)at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:137)at org.hibernate.event.def.AbstractFlushingEventListener.performExecutions(AbstractFlushingEventListener.java:274)at org.hibernate.event.def.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:27)at org.hibernate.impl.SessionImpl.flush(SessionImpl.java:730)at org.springframework.orm.hibernate3.HibernateAccessor.flushIfNecessary(HibernateAccessor.java:394)at org.springframework.orm.hibernate3.HibernateTemplate.execute(HibernateTemplate.java:366)at org.springframework.orm.hibernate3.HibernateTemplate.saveOrUpdateAll(HibernateTemplate.java:707)at com.flex.dao.impl.UserDAO.saveOrUpdateAll(UserDAO.java:68)at com.flex.service.impl.IUserServiceImpl.saveOrUpdateAll(IUserServiceImpl.java:25)at com.flex.web.UserAction.saveAll(UserAction.java:32)at com.flex.web.UserAction.getAllUser(UserAction.java:23)at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)at java.lang.reflect.Method.invoke(Method.java:597)at flex.messaging.services.remoting.adapters.JavaAdapter.invoke(JavaAdapter.java:418)at flex.messaging.services.RemotingService.serviceMessage(RemotingService.java:183)at flex.messaging.MessageBroker.routeMessageToService(MessageBroker.java:1400)at flex.messaging.endpoints.AbstractEndpoint.serviceMessage(AbstractEndpoint.java:1005)at flex.messaging.endpoints.amf.MessageBrokerFilter.invoke(MessageBrokerFilter.java:103)at flex.messaging.endpoints.amf.LegacyFilter.invoke(LegacyFilter.java:158)at flex.messaging.endpoints.amf.SessionFilter.invoke(SessionFilter.java:44)at flex.messaging.endpoints.amf.BatchProcessFilter.invoke(BatchProcessFilter.java:67)at flex.messaging.endpoints.amf.SerializationFilter.invoke(SerializationFilter.java:166)at flex.messaging.endpoints.BaseHTTPEndpoint.service(BaseHTTPEndpoint.java:291)at flex.messaging.MessageBrokerServlet.service(MessageBrokerServlet.java:353)at javax.servlet.http.HttpServlet.service(HttpServlet.java:803)上面日志执行了user.setUserId(id),,数据库不是自增在创建User这个对象时 不执行user.setUserId(id);这时生成的sql是插入语句,但是会出现如下错误因为userid不能为空,数据库又不是自增的原因2011-11-22 11:49:04,052 [http-8080-3] DEBUG org.hibernate.util.JDBCExceptionReporter- could not insert: [com.flex.model.User] [insert into user (user_name, real_name, password, sex, birthday, email, address, telephone, qq, authority, remarks) values (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)]java.sql.SQLException: Field 'user_id' doesn't have a default valueat com.mysql.jdbc.SQLError.createSQLException(SQLError.java:1073)at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:3603)at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:3535)at com.mysql.jdbc.MysqlIO.sendCommand(MysqlIO.java:1989)at com.mysql.jdbc.MysqlIO.sqlQueryDirect(MysqlIO.java:2150)at com.mysql.jdbc.ConnectionImpl.execSQL(ConnectionImpl.java:2626)at com.mysql.jdbc.PreparedStatement.executeInternal(PreparedStatement.java:2119)at com.mysql.jdbc.PreparedStatement.executeUpdate(PreparedStatement.java:2415)at com.mysql.jdbc.PreparedStatement.executeUpdate(PreparedStatement.java:2333)at com.mysql.jdbc.PreparedStatement.executeUpdate(PreparedStatement.java:2318)at org.hibernate.persister.entity.BasicEntityPersister.insert(BasicEntityPersister.java:1759)at org.hibernate.persister.entity.BasicEntityPersister.insert(BasicEntityPersister.java:2178)at org.hibernate.action.EntityIdentityInsertAction.execute(EntityIdentityInsertAction.java:34)at org.hibernate.engine.ActionQueue.execute(ActionQueue.java:239)at org.hibernate.event.def.AbstractSaveEventListener.performSaveOrReplicate(AbstractSaveEventListener.java:240)at org.hibernate.event.def.AbstractSaveEventListener.performSave(AbstractSaveEventListener.java:160)at org.hibernate.event.def.AbstractSaveEventListener.saveWithGeneratedId(AbstractSaveEventListener.java:95)at org.hibernate.event.def.DefaultSaveOrUpdateEventListener.saveWithGeneratedOrRequestedId(DefaultSaveOrUpdateEventListener.java:184)at org.hibernate.event.def.DefaultSaveOrUpdateEventListener.entityIsTransient(DefaultSaveOrUpdateEventListener.java:173)at org.hibernate.event.def.DefaultSaveOrUpdateEventListener.performSaveOrUpdate(DefaultSaveOrUpdateEventListener.java:96)at org.hibernate.event.def.DefaultSaveOrUpdateEventListener.onSaveOrUpdate(DefaultSaveOrUpdateEventListener.java:69)at org.hibernate.impl.SessionImpl.saveOrUpdate(SessionImpl.java:468) 问题补充:首先,数据库表是空的,在程序里调用saveOrUpdate方法,产生的sql语句却是 update user set user_name=?, real_name=?, password=?, sex=?, birthday=?, email=?, address=?, telephone=?, qq=?, authority=?, remarks=? where user_id=?这样当然会出错,明明数据库根本没有数据,为什么执行的是修改表结构CREATE TABLE USER( user_id INT PRIMARY KEY NOT NULL,//不是自增 user_name VARCHAR(30), real_name VARCHAR(20), PASSWORD VARCHAR(20), sex VARCHAR(3), birthday VARCHAR(30), email VARCHAR(40), address VARCHAR(50), telephone VARCHAR(20), qq VARCHAR(15), authority VARCHAR(50), remarks VARCHAR(50)配置入下xx.hbm.xml<hibernate-mapping> <class name="com.flex.model.User" table="user" > <id name="userId" type="java.lang.Integer"> <column name="user_id" /> <generator class="native"></generator> </id> <property name="userName" type="java.lang.String"> <column name="user_name" length="30" /> </property> <property name="realName" type="java.lang.String"> <column name="real_name" length="20" /> </property> <property name="password" type="java.lang.String"> <column name="password" length="20" /> </property> <property name="sex" type="java.lang.String"> <column name="sex" length="3" /> </property> <property name="birthday" type="java.lang.String"> <column name="birthday" length="30" /> </property> <property name="email" type="java.lang.String"> <column name="email" length="40" /> </property> <property name="address" type="java.lang.String"> <column name="address" length="50" /> </property> <property name="telephone" type="java.lang.String"> <column name="telephone" length="20" /> </property> <property name="qq" type="java.lang.String"> <column name="qq" length="15" /> </property> <property name="authority" type="java.lang.String"> <column name="authority" length="50" /> </property> <property name="remarks" type="java.lang.String"> <column name="remarks" length="50" /> </property> </class></hibernate-mapping>================================================调用方法源码 hibernate本身的org.springframework.orm.hibernate3.HibernateTemplate.saveOrUpdateAllpublic void saveOrUpdateAll(final Collection entities) throws DataAccessException {executeWithNativeSession(new HibernateCallback<Object>() {public Object doInHibernate(Session session) throws HibernateException {checkWriteOperationAllowed(session);for (Object entity : entities) {session.saveOrUpdate(entity);}return null;}});================================================错误日志22 11:31:28,668 [http-8080-2] ERROR org.hibernate.event.def.AbstractFlushingEventListener- Could not synchronize database state with sessionorg.hibernate.StaleStateException: Batch update returned unexpected row count from update: 0 actual row count: 0 expected: 1at org.hibernate.jdbc.BatchingBatcher.checkRowCount(BatchingBatcher.java:92)at org.hibernate.jdbc.BatchingBatcher.checkRowCounts(BatchingBatcher.java:78)at org.hibernate.jdbc.BatchingBatcher.doExecuteBatch(BatchingBatcher.java:57)at org.hibernate.jdbc.BatchingBatcher.addToBatch(BatchingBatcher.java:33)at org.hibernate.persister.entity.BasicEntityPersister.update(BasicEntityPersister.java:1982)at org.hibernate.persister.entity.BasicEntityPersister.updateOrInsert(BasicEntityPersister.java:1909)at org.hibernate.persister.entity.BasicEntityPersister.update(BasicEntityPersister.java:2149)at org.hibernate.action.EntityUpdateAction.execute(EntityUpdateAction.java:75)at org.hibernate.engine.ActionQueue.execute(ActionQueue.java:239)at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:223)at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:137)at org.hibernate.event.def.AbstractFlushingEventListener.performExecutions(AbstractFlushingEventListener.java:274)at org.hibernate.event.def.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:27)at org.hibernate.impl.SessionImpl.flush(SessionImpl.java:730)at org.springframework.orm.hibernate3.HibernateAccessor.flushIfNecessary(HibernateAccessor.java:394)at org.springframework.orm.hibernate3.HibernateTemplate.execute(HibernateTemplate.java:366)at org.springframework.orm.hibernate3.HibernateTemplate.saveOrUpdateAll(HibernateTemplate.java:707)at com.flex.dao.impl.UserDAO.saveOrUpdateAll(UserDAO.java:68)at com.flex.service.impl.IUserServiceImpl.saveOrUpdateAll(IUserServiceImpl.java:25)at com.flex.web.UserAction.saveAll(UserAction.java:32)at com.flex.web.UserAction.getAllUser(UserAction.java:23)at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)at java.lang.reflect.Method.invoke(Method.java:597)at flex.messaging.services.remoting.adapters.JavaAdapter.invoke(JavaAdapter.java:418)at flex.messaging.services.RemotingService.serviceMessage(RemotingService.java:183)at flex.messaging.MessageBroker.routeMessageToService(MessageBroker.java:1400)at flex.messaging.endpoints.AbstractEndpoint.serviceMessage(AbstractEndpoint.java:1005)at flex.messaging.endpoints.amf.MessageBrokerFilter.invoke(MessageBrokerFilter.java:103)at flex.messaging.endpoints.amf.LegacyFilter.invoke(LegacyFilter.java:158)at flex.messaging.endpoints.amf.SessionFilter.invoke(SessionFilter.java:44)at flex.messaging.endpoints.amf.BatchProcessFilter.invoke(BatchProcessFilter.java:67)at flex.messaging.endpoints.amf.SerializationFilter.invoke(SerializationFilter.java:166)at flex.messaging.endpoints.BaseHTTPEndpoint.service(BaseHTTPEndpoint.java:291)at flex.messaging.MessageBrokerServlet.service(MessageBrokerServlet.java:353)at javax.servlet.http.HttpServlet.service(HttpServlet.java:803)上面日志执行了user.setUserId(id),,数据库不是自增在创建User这个对象时 不执行user.setUserId(id);这时生成的sql是插入语句,但是会出现如下错误因为userid不能为空,数据库又不是自增的原因2011-11-22 11:49:04,052 [http-8080-3] DEBUG org.hibernate.util.JDBCExceptionReporter- could not insert: [com.flex.model.User] [insert into user (user_name, real_name, password, sex, birthday, email, address, telephone, qq, authority, remarks) values (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)]java.sql.SQLException: Field 'user_id' doesn't have a default valueat com.mysql.jdbc.SQLError.createSQLException(SQLError.java:1073)at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:3603)at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:3535)at com.mysql.jdbc.MysqlIO.sendCommand(MysqlIO.java:1989)at com.mysql.jdbc.MysqlIO.sqlQueryDirect(MysqlIO.java:2150)at com.mysql.jdbc.ConnectionImpl.execSQL(ConnectionImpl.java:2626)at com.mysql.jdbc.PreparedStatement.executeInternal(PreparedStatement.java:2119)at com.mysql.jdbc.PreparedStatement.executeUpdate(PreparedStatement.java:2415)at com.mysql.jdbc.PreparedStatement.executeUpdate(PreparedStatement.java:2333)at com.mysql.jdbc.PreparedStatement.executeUpdate(PreparedStatement.java:2318)at org.hibernate.persister.entity.BasicEntityPersister.insert(BasicEntityPersister.java:1759)at org.hibernate.persister.entity.BasicEntityPersister.insert(BasicEntityPersister.java:2178)at org.hibernate.action.EntityIdentityInsertAction.execute(EntityIdentityInsertAction.java:34)at org.hibernate.engine.ActionQueue.execute(ActionQueue.java:239)at org.hibernate.event.def.AbstractSaveEventListener.performSaveOrReplicate(AbstractSaveEventListener.java:240)at org.hibernate.event.def.AbstractSaveEventListener.performSave(AbstractSaveEventListener.java:160)at org.hibernate.event.def.AbstractSaveEventListener.saveWithGeneratedId(AbstractSaveEventListener.java:95)at org.hibernate.event.def.DefaultSaveOrUpdateEventListener.saveWithGeneratedOrRequestedId(DefaultSaveOrUpdateEventListener.java:184)at org.hibernate.event.def.DefaultSaveOrUpdateEventListener.entityIsTransient(DefaultSaveOrUpdateEventListener.java:173)at org.hibernate.event.def.DefaultSaveOrUpdateEventListener.performSaveOrUpdate(DefaultSaveOrUpdateEventListener.java:96)at org.hibernate.event.def.DefaultSaveOrUpdateEventListener.onSaveOrUpdate(DefaultSaveOrUpdateEventListener.java:69)at org.hibernate.impl.SessionImpl.saveOrUpdate(SessionImpl.java:468)
解决方案
不好意思,刚只看你的配置文件,没看你数据库设计你数据库设计时,字段:user_id 不是自增的,对吧,也就是说主键是程序负责产生对吧?那么分两种情况:①、如果是你自己写程序产生主键user_id,那么你应该将配置文件中的主键生产策略改为:assigned(表示是用户自定义id),而不是你定义的native(表示由底层数据库自己产生),所以你应该将主键的配置改为:<id name="userId" type="java.lang.Integer"> <column name="user_id" /> <generator class="assigned"></generator> </id> ②、如果默认采用hibernate自动生产主键user_id,那么你应该选择一种Hibernate主键生成策略,如果uuid.hex(按照实际情况,可能用其他,你可网上查下,有好几个)然后配置如下:<id name="userId" type="java.lang.Integer"> <column name="user_id" /> <generator class="uuid.hex"></generator> </id>
解决方案二:
将你的User对象的user_id设置为null,应该就可以了!
解决方案三:
你设置的持久化类的id生成器为native,则默认 unsaved-value属性值为null,即对象user_id字段必须为null,hibernate才会看是否数据库中有对应记录,也就是判断是否是脱管管对象,如不存在相应记录,即瞬时对象,hibernate才执行保存,想让session.saveOrUpdate()执行save操作,必须将PO(你将要保存的对象)的id设为空。