Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

StaleStateException when saving entity with complex relations

The hibernate entity I am saving in the database (Oracle) has very complex relations, in the sense that it has many related entities. It looks something like this...

@Table(name = "t_HOP_CommonContract")
public class Contract {
    @Id
    private ContractPK id;

    @OneToOne(fetch = FetchType.LAZY, cascade = CascadeType.ALL)
    @PrimaryKeyJoinColumn
    private ContractGroupMember contractGroupMember;

    @OneToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY)
    @JoinColumns({
        @JoinColumn(name = "TransactionId", referencedColumnName = "TransactionId"),
        @JoinColumn(name = "PrimaryContractId", referencedColumnName = "PrimaryContractId")
    })
    @Fetch(FetchMode.SUBSELECT)
    private List<ContractLink> contractLinks;

    // . . . . . . . 

    // A couple of more one to many relationships

    // Entity getters etc.

}

I also have a couple of more entities such as...

@Table(name = "t_HOP_TRS")
public class TotalReturnSwap {
    @Id
    private ContractPK id;
    // Entity Getters etc.
}

The trick is that I have to do persistence of Contract and TotalReturnSwap entities in the same transaction.

Sometimes it could be a bunch of entities that have to be persisted in the same transaction.

I have noticed the following exception when I save the TotalReturnSwap entity (which is always done after I have saved the Contract entity).

org.springframework.orm.hibernate3.HibernateOptimisticLockingFailureException: Batch update returned unexpected row count from update [0]; actual row count: 0; expected: 1; nested exception is
    org.hibernate.StaleStateException: Batch update returned unexpected row count from update [0]; actual row count: 0; expected: 1
    at org.springframework.orm.hibernate3.SessionFactoryUtils.convertHibernateAccessException(SessionFactoryUtils.java:675) \
    at org.springframework.orm.hibernate3.HibernateTransactionManager.convertHibernateAccessException(HibernateTransactionManager.java:793) 
    at org.springframework.orm.hibernate3.HibernateTransactionManager.doCommit(HibernateTransactionManager.java:664) 
    at org.springframework.transaction.support.AbstractPlatformTransactionManager.processCommit(AbstractPlatformTransactionManager.java:754) 
    at org.springframework.transaction.support.AbstractPlatformTransactionManager.commit(AbstractPlatformTransactionManager.java:723) 
    at org.springframework.transaction.support.TransactionTemplate.execute(TransactionTemplate.java:147) 
    at com.rbs.fcg.publishing.DownstreamContractBusinessEventPostingService.performTDWPersistenceForContracts(DownstreamContractBusinessEventPostingService.java:102) 
    at com.rbs.fcg.publishing.DownstreamContractBusinessEventPostingService.persistContractBusinessEvent(DownstreamContractBusinessEventPostingService.java:87)
    at com.rbs.fcg.publishing.DownstreamContractBusinessEventPostingService.publish(DownstreamContractBusinessEventPostingService.java:67)
    at com.rbs.fcg.publishing.PublishingProcessor.publish(PublishingProcessor.java:76)
    at com.rbs.fcg.publishing.PublishingProcessor.process(PublishingProcessor.java:52)
    at com.rbs.are.MultiThreadedQueueItemProcessor$2.run(MultiThreadedQueueItemProcessor.java:106)
    at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908)
    at java.lang.Thread.run(Thread.java:662)
Caused by: 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)

Now a few points that may help while answering questions:

  • I am only saving (inserting) entities in database - never updating/ deleting/ reading
  • I have been able to isolate this exception even in single threaded environments, so it does not look like a multi-threading, issue even though our application is multi-threaded
like image 321
user1564710 Avatar asked Jul 31 '12 05:07

user1564710


1 Answers

The error can be caused by several things:

  1. Flushing the data before committing the object may lead to clear all object pending for persist.
  2. If object has primary key which is auto generated and you are forcing an assigned key
  3. if you are cleaning the object before committing the object to database.
  4. Zero or Incorrect ID: If you set the ID to zero or something else, Hibernate will try to update instead of insert.
  5. Object is Stale: Hibernate caches objects from the session. If the object was modified, and Hibernate doesn’t know about it, it will throw this exception — note the StaleStateException

I'm not taking the credit for it, found it here.

like image 174
Tomer Avatar answered Sep 19 '22 18:09

Tomer