我正在尝试从数据库中删除记录,但在删除它之前,我将其中一个子项复制到另一个记录中,这会导致以下错误。
SEVERE: 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:59)
at org.hibernate.persister.entity.AbstractEntityPersister.update(AbstractEntityPersister.java:3224)
at org.hibernate.persister.entity.AbstractEntityPersister.updateOrInsert(AbstractEntityPersister.java:3126)
at org.hibernate.persister.entity.AbstractEntityPersister.update(AbstractEntityPersister.java:3456)
at org.hibernate.action.internal.EntityUpdateAction.execute(EntityUpdateAction.java:140)
at org.hibernate.engine.spi.ActionQueue.execute(ActionQueue.java:364)
at org.hibernate.engine.spi.ActionQueue.executeActions(ActionQueue.java:356)
at org.hibernate.engine.spi.ActionQueue.executeActions(ActionQueue.java:278)
at org.hibernate.event.internal.AbstractFlushingEventListener.performExecutions(AbstractFlushingEventListener.java:328)
at org.hibernate.event.internal.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:52)
at org.hibernate.internal.SessionImpl.flush(SessionImpl.java:1234)
at org.hibernate.internal.SessionImpl.managedFlush(SessionImpl.java:404)
.....
1)在第一个函数中(从记录18中获取列表并添加到新记录中)
....
User user = (User) session.get(User.class, 18L);
tx.commit();
User client = new User();
client.getmyList().setItems(user.getmyList().getItems());
return client;
2)在第二个功能中(删除记录18)
User user = (User) session.get(User.class, 18L);
session.delete(user);
3)在第三个功能中(保存新记录)
session.save(client);
用户类
@Entity
@DynamicUpdate
public class User{
.....
@OneToOne(cascade = CascadeType.ALL)
public UnitWatchList getmyList() {
return myList;
}
...
}
答案 0 :(得分:1)
在session.delete(user);
之后,您是否在第二个功能中关闭了交易?也许您的问题出在session.delete()
而非session.save()
。
如何在items
中映射UnitWatchList
?
此致
答案 1 :(得分:1)
我可能只是写一个DAO方法deleteAndMoveChildrensTo(Long victimId,Long recipientId),像这样:
DAO课程:
public boolean deleteAndMoveChildrensTo(Long victimId, Long recipientId) {
User victim = (User) getSession().load(User.class, victimId);
User recipient = (User) getSession().load(User.class, recipientId);
for (UnitWatchList unitWatch : victim.getmyList().getItems()) {
unitWatch.setUser(recipient);
}
recipient.getmyList().addAll(victim.getmyList().getItems());
getSession().saveOrUpdate(recipient);
getSession().flush();
getSession().evict(victim);
victim = (User) getSession().load(User.class, victimId);
getSession().delete(victim);
return true;
}
和相应的Service类如下
服务类。
@Transactional(readOnly = false, propagation = Propagation.REQUIRED)
public boolean deleteAndMoveChildrensTo(Long victimId, Long recipientId) {
DAO.deleteAndMoveChildrensTo(victimId, recipientId);
}
试试这个希望这会解决你的问题...
答案 2 :(得分:1)
Hibernate有一个默认的第一级缓存,它与会话对象相关联。因此,一旦对对象的访问将被缓存,将从缓存中获取进一步的访问。
其次,将引用对象分配给其他变量只会更改引用。
让我们跟踪您的代码
User user = (User) session.get(User.class, 18L)
client.getmyList().setItems(user.getmyList().getItems());
User user = (User) session.get(User.class, 18L);
中提取的session.delete(user);
session.save(client);
但是,没有实际对象。哪个被删除。原型模式通常用于应对对象。克隆方法也可以被覆盖。但是,一旦创建了实体对象的副本。 hibernate会话不会维护新对象,这是另一个问题。
根据我的拙见,删除一个物品如果再次保存则不是一个好习惯。如果你想保存,为什么要删除?还应重新安排映射以解决这些问题。
另见