0

我正在尝试从数据库中删除一条记录,但在删除它之前,我将它的一个子项复制到另一条记录中,这会遇到以下错误。

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;
    } 

    ...
} 
4

3 回答 3

1

您是否在第二个函数中关闭事务,之后session.delete(user);?也许你的问题是在session.delete()而不是在session.save().

是如何映射itemsUnitWatchList

问候,

于 2013-09-24T06:07:23.497 回答
1

Hibernate 有一个默认的第一级缓存,它与会话对象相关联。因此,一旦对对象的访问将被缓存,并且将从缓存中获取进一步的访问。

其次,将引用对象分配给其他变量只会更改引用。

让我们跟踪您的代码

  1. 您检索一个用户对象,让我们说它在内存位置 (a)User user = (User) session.get(User.class, 18L)
  2. 用户对象被分配给另一个对象。请注意,它仅设置为内存位置。没有实际的副本。client.getmyList().setItems(user.getmyList().getItems());
  3. 再次移除对象。但是,检索到的对象仍然在内存位置(a)中,因为它是从缓存中获取的User user = (User) session.get(User.class, 18L);
  4. 删除内存位置中的对象 (a)session.delete(user);
  5. 尝试保存一个对象,该对象还涉及位于内存位置的用户对象 (a)session.save(client);但是,没有实际的对象。哪个被删除。

原型模式通常用于应对对象。克隆方法也可以被覆盖。但是,一旦创建了实体对象的副本。新对象不会被休眠会话维护,这是另一个问题。

在我谦虚的想法中,如果将再次保存对象,则删除它不是一个好习惯。如果要保存,为什么要删除?映射也应该重新排列以解决这些问题。

也可以看看

原型模式

休眠缓存

类型、值和变量

于 2013-09-24T07:25:32.333 回答
1

我可能只会写一个 DAO 方法 deleteAndMoveChildrensTo(LongvictimId, 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;
    }

和相应的服务类如下

服务类。

@Transactional(readOnly = false, propagation = Propagation.REQUIRED)
public boolean deleteAndMoveChildrensTo(Long victimId, Long recipientId) {
    DAO.deleteAndMoveChildrensTo(victimId, recipientId);
}

试试这个希望这能解决你的问题......

于 2013-09-24T06:56:07.530 回答