【发布时间】:2011-12-01 10:27:04
【问题描述】:
我正在尝试通过 Hibernate 映射到 MySQL 表来实现一些 Java 对象的持久性。当我提交时,我收到一条消息说'批量更新从更新 [0] 中返回了意外的行数;实际行数:0;预计:1'。
我的假设是,问题是由于我的 Java POJO 中有一个 long-字段,我想将其用作 MySQL 表中的主键。由于我无法在 MySQL 表中使用数据类型 LONG 作为我的主键(错误 1170:BLOB/TEXT 列 'id' 在没有键长度的键规范中使用)我从一些谷歌搜索得出结论,这个post BIGINT 将是long 的合适映射。但是它没有更新。
我的测试POJOPerson很简单。它有 3 个字段:id (long)、firstname (String)、lastname (String) 以及 setter 和 getter 等。
我在 xml (person.hbm.xml) 中进行休眠映射,基本上看起来像(减去标题):
<hibernate-mapping>
<class name="hibernatetest.Person" table="hibernatetest">
<id name="id" type="long" column="id" >
<generator class="native"/>
</id>
<property name="firstname">
<column name="firstname" />
</property>
<property name="lastname">
<column name="lastname"/>
</property>
</class>
</hibernate-mapping>
我应该保存或更新记录的实际 java 代码 sn-p 很简单:
Transaction tr = session.beginTransaction();
Person person = new Person(1,"John","Doe");
session.saveOrUpdate(person);
tr.commit();
事情就是这样,如果我在 Person 对象和 MySQL 表中将 id 的类型更改为 int(整数),这一切都可以正常工作。但是,对于要保留的实际对象,我没有该选项,所以问题是;我做错了什么或者我应该怎么做才能让它工作?谢谢。
添加堆栈跟踪:
Hibernate: update hibernatetest set firstname=?, lastname=? where id=?
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:81)
at org.hibernate.jdbc.Expectations$BasicExpectation.verifyOutcome(Expectations.java:73)
at org.hibernate.engine.jdbc.batch.internal.NonBatchingBatch.addToBatch(NonBatchingBatch.java:57)
at org.hibernate.persister.entity.AbstractEntityPersister.update(AbstractEntityPersister.java:3006)
at org.hibernate.persister.entity.AbstractEntityPersister.updateOrInsert(AbstractEntityPersister.java:2908)
at org.hibernate.persister.entity.AbstractEntityPersister.update(AbstractEntityPersister.java:3237)
at org.hibernate.action.internal.EntityUpdateAction.execute(EntityUpdateAction.java:113)
at org.hibernate.engine.spi.ActionQueue.execute(ActionQueue.java:273)
at org.hibernate.engine.spi.ActionQueue.executeActions(ActionQueue.java:265)
at org.hibernate.engine.spi.ActionQueue.executeActions(ActionQueue.java:187)
at org.hibernate.event.internal.AbstractFlushingEventListener.performExecutions(AbstractFlushingEventListener.java:337)
at org.hibernate.event.internal.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:50)
at org.hibernate.internal.SessionImpl.flush(SessionImpl.java:1082)
at org.hibernate.internal.SessionImpl.managedFlush(SessionImpl.java:317)
at org.hibernate.engine.transaction.internal.jdbc.JdbcTransaction.beforeTransactionCommit(JdbcTransaction.java:101)
at org.hibernate.engine.transaction.spi.AbstractTransactionImpl.commit(AbstractTransactionImpl.java:175)
at com.hibernate.test.TestMain.main(TestMain.java:38)
nested transactions not supported
更新: 好的,我终于解决了。我将休眠生成器类从“本机”更改为“分配”,现在它按预期工作。所以现在休眠映射看起来像:
<hibernate-mapping>
<class name="hibernatetest.Person" table="hibernatetest">
<id name="id" type="long" column="id" >
<generator class="assigned"/>
</id>
<property name="firstname">
<column name="firstname" />
</property>
<property name="lastname">
<column name="lastname"/>
</property>
</class>
</hibernate-mapping>
必须承认我不知道该参数的含义(从某处复制)并且不知道它会引起如此头痛。发现这个explanation 很有用。
显然我没有足够的凭据来回答我自己的问题,所以我猜它会保持开放,或者如果有人提供空答案,我会接受它。谢谢。
【问题讨论】:
-
你能发布你的完整堆栈跟踪吗,long 和 BIGINT 应该可以正常工作,我个人使用它没有发现问题,请分享你的堆栈跟踪
-
你的 db 列类型定义是什么?你的 id 属性类型呢?无论如何,列的 Bigint 和 java 属性的 Long 都可以。
-
@mprabhat 完成。它有一条消息说我以前没有看到“不支持嵌套事务”。不知道是什么意思?
-
@polypiel 抱歉,我不确定我是否理解这个问题。 MySQL 中的数据类型是 BIGINT(20),而 hibernate 配置就是我上面发布的所有内容。
-
意识到“不支持嵌套事务”可能是另一个单独的异常引发,因为我试图在前一个事务失败时开始一个新事务。所以它在这种情况下不相关。