Java Hibernate-批处理更新从更新返回意外的行数:0实际行数:0预期:1
我得到以下休眠错误。我能够确定导致问题的功能。不幸的是,函数中有几个DB调用。我找不到导致问题的行,因为hibernate在事务结束时刷新会话。下面提到的hibernate错误看起来像一般错误。它甚至没有提到是哪个Bean导致了这个问题。有人熟悉这个休眠错误吗Java Hibernate-批处理更新从更新返回意外的行数:0实际行数:0预期:1,java,hibernate,Java,Hibernate,我得到以下休眠错误。我能够确定导致问题的功能。不幸的是,函数中有几个DB调用。我找不到导致问题的行,因为hibernate在事务结束时刷新会话。下面提到的hibernate错误看起来像一般错误。它甚至没有提到是哪个Bean导致了这个问题。有人熟悉这个休眠错误吗 org.hibernate.StaleStateException: Batch update returned unexpected row count from update: 0 actual row count: 0 expect
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:142)
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 org.springframework.orm.hibernate3.HibernateTransactionManager.doCommit(HibernateTransactionManager.java:584)
at org.springframework.transaction.support.AbstractPlatformTransactionManager.processCommit(AbstractPlatformTransacti
onManager.java:500)
at org.springframework.transaction.support.AbstractPlatformTransactionManager.commit(AbstractPlatformTransactionManag
er.java:473)
at org.springframework.transaction.interceptor.TransactionAspectSupport.doCommitTransactionAfterReturning(Transaction
AspectSupport.java:267)
at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:106)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:170)
at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:176)
如果没有事务的代码和映射,调查问题几乎是不可能的 但是,要更好地了解问题的原因,请尝试以下操作:
<hibernate-mapping>
<class name="path.to.class.Principal" table="principal_table" ...>
...
<set name="middleObjects" table="middle_table" inverse="true" fetch="select">
<key>
<column name="PRINCIPAL_ID" not-null="true" />
</key>
<one-to-many class="path.to.class.Middel" />
</set>
...
- 在hibernate配置中,将hibernate.show_sql设置为true。这将向您显示执行的SQL以及导致问题的SQL
- 将Spring和Hibernate的日志级别设置为DEBUG,这同样会让您更好地了解是哪一行导致了问题
- 创建一个单元测试,它可以复制问题,而无需在Spring中配置事务管理器。这将使您更好地了解这一行有问题的代码
希望能有所帮助。我在删除一条完全不存在的Id记录时遇到了相同的异常。因此,请检查您正在更新/删除的记录是否确实存在于DB中。我刚刚遇到这个问题,并发现我正在删除一个记录,然后在Hibernate事务中尝试更新它 如前所述,当对象的子对象被删除时,会发生这种情况。(可能是因为需要对整个父对象进行更新,有时我们更喜欢删除子对象并在父对象上重新插入它们(新的、旧的都不重要),以及父对象可能对其任何其他普通字段进行的任何其他更新) 因此…为了使这项工作正常,请通过调用
childrenList.clear()
(不要循环遍历子项,并使用一些childDAO.delete(childrenList.get(i.delete())和设置来删除子项(在事务中)
@OneToMany(cascade=CascadeType.XXX,orphaneremovation=true)
位于父对象的一侧。然后更新父亲(fatherDAO.update(父亲))。(对每个父对象重复)结果是,子对象与父对象的链接被剥离,然后它们被框架作为孤立对象删除。当您尝试删除同一对象,然后再次更新同一对象时,会发生这种情况。请在删除后使用此选项
session.clear() 当触发器执行影响行计数的附加DML(数据修改)查询时,可能会发生这种情况。我的解决方案是在触发器顶部添加以下内容:
SET NOCOUNT ON;
有一次,当我给一些对象分配特定的ID(测试)时,这种情况发生在我身上,然后我试图将它们保存在数据库中。问题是在数据库中有一个特定的策略用于设置对象的ID。如果您有Hibernate级别的策略,请不要分配ID。我遇到了相同的问题,我验证了这可能是由于自动递增主键造成的。要解决此问题,请不要在数据集中插入自动增量值。插入没有主键的数据。我遇到了这个问题,我们有一个多关系
在master的hibernate hbm映射文件中,对于具有set-type排列的对象,添加了cascade=“save-update”
,效果良好
如果不这样做,默认情况下hibernate会尝试更新不存在的记录,并通过这样做,它会插入记录。解决方案:
在id属性的Hibernate映射文件中,如果使用任何生成器类,则不应使用setter方法显式设置该属性的值
如果显式设置Id属性的值,则会导致上述错误。选中此选项可避免此错误。
或
当您在映射文件中提到字段生成器=“native”或“incremental”并且在数据库中映射的表没有自动递增时,会显示错误
解决方案:转到数据库并更新表以设置自动增量当我在注释为@Transactional
的方法中手动开始和提交事务时,遇到了这个问题。我通过检测活动事务是否已经存在,修复了这个问题
//Detect underlying transaction
if (session.getTransaction() != null && session.getTransaction().isActive()) {
myTransaction = session.getTransaction();
preExistingTransaction = true;
} else {
myTransaction = session.beginTransaction();
}
然后我允许Spring处理提交事务
private void finishTransaction() {
if (!preExistingTransaction) {
try {
tx.commit();
} catch (HibernateException he) {
if (tx != null) {
tx.rollback();
}
log.error(he);
} finally {
if (newSessionOpened) {
SessionFactoryUtils.closeSession(session);
newSessionOpened = false;
maxResults = 0;
}
}
}
}
这也发生在我身上,因为我的id和视图一样长,并且我从视图接收到值0,当我试图保存到数据库中时,我得到了这个错误,然后我通过将id设置为null来修复它。当您将JSF托管Bean声明为
@RequestScoped;
你什么时候应该申报为
@SessionScoped;
问候 我也面临同样的问题。
代码在测试环境中工作。但它在登台环境中不起作用
org.hibernate.jdbc.BatchedTooManyRowsAffectedException: Batch update returned unexpected row count from update [0]; actual row count: 3; expected: 1
问题是,在测试DB表时,表的每个主键都有一个条目。但在暂存数据库中,同一主键有多个条目。(问题是在暂存数据库中,表没有任何主键约束,并且存在多个条目。)
所以每次更新操作都会失败。它尝试更新单个记录,并期望更新计数为1。但由于同一主键在表中有3条记录,因此结果更新计数为3条。因为预期更新计数和实际结果更新计数不匹配,所以它抛出异常并回滚
之后,我删除了所有具有重复主键的记录,并添加了主键约束。它工作得很好
Hibernate - Batch update returned unexpected row count from update: 0 actual row count: 0 expected: 1
实际行数:0//表示未找到要更新的记录
更新:0//表示未找到任何记录,因此未进行任何更新
预期:1//表示预期至少有一条记录,其键位于db表中
这里的问题是,查询试图更新某个键的记录,但hibernate没有
session.beginTransaction();
Principal principal = new Principal();
principal.setSomething("1");
principal.setSomethingElse("2");
Middle middleObject = new Middle();
middleObject.setSomething("1");
middleObject.setPrincipal(principal);
principal.getMiddleObjects().add(middleObject);
session.saveOrUpdate(principal);
session.saveOrUpdate(middleObject); // NOTICE: you will need to save it manually
session.getTransaction().commit();
SessionFactory sf=new Configuration().configure().buildSessionFactory();
Session session=sf.openSession();
UserDetails user=new UserDetails();
session.beginTransaction();
user.setUserName("update user agian");
user.setUserId(12);
session.saveOrUpdate(user);
session.getTransaction().commit();
System.out.println("user::"+user.getUserName());
sf.close();
Detail detail = getDetail(Long.valueOf(1396451));
session.delete(detail);
session.flush();
session.delete(detail);
session.flush();
try
{
if(!session.isOpen())
{
session=EmployeyDao.getSessionFactory().openSession();
}
tx=session.beginTransaction();
session.evict(e);
session.saveOrUpdate(e);
tx.commit();;
EmployeyDao.shutDown(session);
}
catch(HibernateException exc)
{
exc.printStackTrace();
tx.rollback();
}
if ( expectedRowCount > rowCount ) {
throw new StaleStateException(
"Batch update returned unexpected row count from update ["
+ batchPosition + "]; actual row count: " + rowCount
+ "; expected: " + expectedRowCount + "; statement executed: "
+ statement
);
}
@Entity(name = "Post")
@Table(name = "post")
public class Post {
@Id
@GeneratedValue(strategy = GenerationType.SEQUENCE)
private Long id;
private String title;
@Version
private short version;
public Long getId() {
return id;
}
public Post setId(Long id) {
this.id = id;
return this;
}
public String getTitle() {
return title;
}
public Post setTitle(String title) {
this.title = title;
return this;
}
public short getVersion() {
return version;
}
}
properties.put("hibernate.jdbc.batch_size", "5");
properties.put("hibernate.order_inserts", "true");
properties.put("hibernate.order_updates", "true");
doInJPA(entityManager -> {
for (int i = 1; i <= 3; i++) {
entityManager.persist(
new Post()
.setTitle(String.format("Post no. %d", i))
);
}
});
SELECT nextval ('hibernate_sequence')
SELECT nextval ('hibernate_sequence')
SELECT nextval ('hibernate_sequence')
Query: [
INSERT INTO post (title, version, id)
VALUES (?, ?, ?)
],
Params:[
(Post no. 1, 0, 1),
(Post no. 2, 0, 2),
(Post no. 3, 0, 3)
]
doInJPA(entityManager -> {
List<Post> posts = entityManager.createQuery("""
select p
from Post p
""", Post.class)
.getResultList();
posts.forEach(
post -> post.setTitle(
post.getTitle() + " - 2nd edition"
)
);
executeSync(
() -> doInJPA(_entityManager -> {
Post post = _entityManager.createQuery("""
select p
from Post p
order by p.id
""", Post.class)
.setMaxResults(1)
.getSingleResult();
post.setTitle(post.getTitle() + " - corrected");
})
);
});
Query:[
UPDATE
post
SET
title = ?,
version = ?
WHERE
id = ? AND
version = ?
],
Params:[
('Post no. 1 - corrected', 1, 1, 0)
]
Query:[
UPDATE
post
SET
title = ?,
version = ?
WHERE
id = ? AND
version = ?
],
Params:[
('Post no. 1 - 2nd edition', 1, 1, 0),
('Post no. 2 - 2nd edition', 1, 2, 0),
('Post no. 3 - 2nd edition', 1, 3, 0)
]
o.h.e.j.b.i.AbstractBatchImpl - HHH000010: On release of batch it still contained JDBC statements
o.h.e.j.b.i.BatchingBatch - HHH000315: Exception executing batch [
org.hibernate.StaleStateException:
Batch update returned unexpected row count from update [0];
actual row count: 0;
expected: 1;
statement executed:
PgPreparedStatement [
update post set title='Post no. 3 - 2nd edition', version=1 where id=3 and version=0
]
],
SQL: update post set title=?, version=? where id=? and version=?