6

データベース (Oracle) に保存している休止状態のエンティティには、多くの関連エンティティがあるという意味で、非常に複雑な関係があります。なんかこんな感じ…

@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.

}

また、次のようなエンティティがいくつかあります...

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

秘訣は、同じトランザクションでエンティティContractとエンティティの永続化を行う必要があることです。TotalReturnSwap

場合によっては、同じトランザクションで永続化する必要があるエンティティの束である可能性があります。

エンティティを保存すると、次の例外に気付きましたTotalReturnSwap(これは、エンティティを保存した後に常に行われContractます)。

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)

質問に答える際に役立つかもしれないいくつかのポイント:

  • データベースにエンティティを保存(挿入)しているだけです-更新/削除/読み取りはありません
  • シングルスレッド環境でもこの例外を分離できたので、アプリケーションがマルチスレッドであっても、マルチスレッドの問題のようには見えません。
4

2 に答える 2

20

このエラーは、いくつかの原因で発生する可能性があります。

  1. オブジェクトをコミットする前にデータをフラッシュすると、永続化のために保留中のすべてのオブジェクトがクリアされる可能性があります。
  2. オブジェクトに自動生成された主キーがあり、割り当てられたキーを強制している場合
  3. オブジェクトをデータベースにコミットする前にオブジェクトを消去する場合。
  4. ゼロまたは不正な ID: ID をゼロまたはその他に設定すると、Hibernate は挿入ではなく更新を試みます。
  5. オブジェクトが古い: Hibernate はセッションからオブジェクトをキャッシュします。オブジェクトが変更され、Hibernate がそれを認識していない場合、この例外がスローされます — StaleStateException に注意してください。

私はそれを信用していません。ここで見つけました。

于 2012-07-31T09:07:24.693 に答える
0

これは、次の状況で私に起こりました。

  • Java コードで objectA を作成しました。
  • 既存の objectB を objectA にフィールドとして追加しました。objectB は objectA と 1 対 1 の関係にあります。
  • objectA をデータベースに保存 (作成) しました。
  • objectA が保存されると、objectB がデータベースで更新され、objectA の ID が追加されました。

  • 次に、objectC を objectA に追加しました (複数の objectC に対して 1 つの objectA)。objectA を更新しようとしたところ、stalestateexception が発生しました....マージを使用している場合でも。

答えは、objectB を更新するか、データベースから objectA の新しいインスタンスを取得する必要があるということです。

于 2016-10-25T19:15:48.987 に答える