2011-02-23 37 views
5

有时候持久obj时,它的一个字段太大而不能放入db字段,导致数据截断异常。在下面的代码中,我试图捕获DataException并简单地清空该字段和resave。但是,我在重新保存时遇到异常。为什么批量更新异常发生,我该如何解决它?org.hibernate.StaleStateException:批量更新从update [0]返回意外的行数;实际行数:0;预期:1

 

public static void save(Object obj) throws Exception{ 
     try{ 
      beginTransaction(); 
      getSession().save(obj); 
      commitTransaction(); 

     }catch(Exception e){ 
      e.printStackTrace(); 
      rollbackTransaction(); 
      throw e; 
     }finally{ 
      closeSession(); //not needed, session obtained from sf.getCurrentSession() will auto close 
     } 
    } 
public static void saveXXX(XXX rec){ 

     try { 
      save(rec); 
     } catch (org.hibernate.exception.DataException e) { 
      e.printStackTrace(); 

      saveXXX(rec, e); //causes an exception  
     } catch (Exception e) { 
      e.printStackTrace(); 
     } 

    } 
    private static void saveXXX(WhoisRecord rec, DataException e) { 
     rec.setField(""); //empty out the problem field 
     saveXXX(rec); 

例外:

 
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:85) 
    at org.hibernate.jdbc.Expectations$BasicExpectation.verifyOutcome(Expectations.java:70) 
    at org.hibernate.jdbc.BatchingBatcher.checkRowCounts(BatchingBatcher.java:90) 
    at org.hibernate.jdbc.BatchingBatcher.doExecuteBatch(BatchingBatcher.java:70) 
    at org.hibernate.jdbc.AbstractBatcher.executeBatch(AbstractBatcher.java:268) 
    at org.hibernate.jdbc.AbstractBatcher.prepareStatement(AbstractBatcher.java:114) 
    at org.hibernate.jdbc.AbstractBatcher.prepareStatement(AbstractBatcher.java:109) 
    at org.hibernate.jdbc.AbstractBatcher.prepareBatchStatement(AbstractBatcher.java:244) 
    at org.hibernate.persister.entity.AbstractEntityPersister.update(AbstractEntityPersister.java:2382) 
    at org.hibernate.persister.entity.AbstractEntityPersister.updateOrInsert(AbstractEntityPersister.java:2335) 
    at org.hibernate.persister.entity.AbstractEntityPersister.update(AbstractEntityPersister.java:2635) 
    at org.hibernate.action.EntityUpdateAction.execute(EntityUpdateAction.java:115) 
    at org.hibernate.engine.ActionQueue.execute(ActionQueue.java:279) 
    at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:263) 
    at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:168) 
    at org.hibernate.event.def.AbstractFlushingEventListener.performExecutions(AbstractFlushingEventListener.java:321) 
    at org.hibernate.event.def.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:50) 
    at org.hibernate.impl.SessionImpl.flush(SessionImpl.java:1027) 
    at org.hibernate.impl.SessionImpl.managedFlush(SessionImpl.java:365) 
    at org.hibernate.transaction.JDBCTransaction.commit(JDBCTransaction.java:137) 
. 
. 
. 

回答

2

我没有足够的线索,以确切地告诉你。我可以说我有同样的问题,并通过调用merge()而不是save()来解决。如果分离的对象,你应该总是使用merge()。

3

我不是这方面的专家,但我认为我只是有相同的问题,但在相反的方向。

看起来发生了什么是你试图保存记录,Hibernate会抛出该数据截断异常,这意味着它保存了一些东西,但不是所有你想要的东西。因此,您捕获该异常,并尝试回滚事务。但是这并不总是保证成功(从我在Hibernate save() and transaction rollback上看到的),所以保存的数据仍然可以在那里。我们假设它是。接下来你改变你的记录,并尝试再次保存它。

但由于数据仍然存在,调用保存将不会执行任何操作,因为在这种情况下,它应该是更新。所以当你尝试提交这个事务时,Hibernate知道你想保存1条记录,但是它成功地保存了0,因此出现了错误。

尝试更改getSession()。save(obj);getSession()。saveOrUpdate(obj);。当它不存在时应该保存记录,并在记录更新它时(不要过大字段)。

3

我得到这个错误是因为我在类映射中有错误的键生成器,然后我在同一个事务中先做了一个插入操作,然后再做了一个更新操作。

键列定义为自动增量(在MySQL),以及与此映射

<id name="tableId" type="long" access="field"> 
    <column name="tableId" /> 
    <generator class="assigned" /> 
</id> 

我有一个StaleStateException,但是当我纠正了进入

<id name="tableId" type="long" access="field"> 
    <column name="tableId" /> 
    <generator class="native" /> 
</id> 

那么它运作良好没有什么问题。

+0

你是最棒的,你拯救了我的一天 – BSeitkazin 2015-11-25 05:40:51

1

我所经历的,更新对象时,此异常升高有其表不存在的ID。如果您读取异常消息,则表示“批量更新返回来自update [0]的意外行数;实际行数:0; expected:1”,这意味着无法使用您的给定ID找到记录。

为了避免这种情况,我总是用相同的id读取记录,如果我发现记录,然后我打电话更新,否则抛出“异常记录未找到”。

相关问题