2013-09-24 73 views
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);    

User类

@Entity 
@DynamicUpdate 
public class User{ 

    ..... 

    @OneToOne(cascade = CascadeType.ALL) 
    public UnitWatchList getmyList() { 
     return myList; 
    } 

    ... 
} 
+1

请提供完整的堆栈跟踪,也'User'代码可以帮助 – 2013-09-24 05:23:18

+0

问题是更新 – J888

回答

1

Hibernate有一个默认的第一级缓存与会话对象关联。所以,一旦访问一个对象将被缓存,进一步的访问将从缓存中获取。

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

让跟踪代码

  1. 您检索用户对象,可以说,它的存储位置(一)User user = (User) session.get(User.class, 18L)
  2. 用户对象assiged到另一个对象。请注意,它仅被设置为内存位置。没有实际的副本。 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);但是,没有实际的对象。哪些被删除。

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

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

又见

Prototype Pattern

Hibernate Caching

Types, Values, and Variables

+0

我认为是我返回该对象,并在其他功能中使用它的位置会改变。 – J888

+0

编号一级缓存是休眠状态下的默认缓存。 – erencan

1

你在第二个函数关闭交易,session.delete(user);后?也许你的问题在session.delete()而不是session.save()。如何映射itemsUnitWatchList

问候,

1

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

尝试了这一点,希望这将解决您的问题...

相关问题