1

JPA (2.0)/Hibernate (3.5.6) と一緒に Spring (3.11) データ/リポジトリを使用していますが、CrudRepository の save メソッドに問題があります。

私が持っているグローバルサービスは次のとおりです。

@Override
@Transactional(readOnly = false, propagation = Propagation.REQUIRED, rollbackFor = Throwable.class)
public MyBean createMyBean(MyBean myBean) {


    // 1)
    // myBean does not have PK, it will be generated via sequence
    MyBean myBean = myBeanRepository.save(myBean);

    // 2)
    // sends event to queue
    syncEventProducer.sendSyncEvent(....);

    return myBean;
}

私の問題は単純です:テーブルの要件を満たさない特定の myBean を意図的に挿入しています (通常、DB で null として作成された列を null として設定しています)。その後、例外 (DataIntegrityViolationException など) が内部的に生成されています。呼び出しで 1) しかし 2) それでも実行されます。何故ですか?

MyBeanRepository は次のようになります。

public interface MyBeanRepository extends CrudRepository<MyBean, Integer> {

}

コードを少し掘り下げると、リポジトリに関連する SimpleJpaRepository が実際に新しい PK を持つ Bean を返すことがわかりました。

もちろん、最後にトランザクション全体がロールバックされますが、なぜ myBeanRepository.save(myBean) が例外を「飲み込み」、代わりに新しい PK を持つ新しい Bean を返すのか理解できません。

ありがとう、

ハビ

4

1 に答える 1

4

Transactionalメソッドにアノテーションがある場合createMyBean、トランザクションはメソッドの最後でのみ完了するためだと思います。Hibernate session.flush()は、明示的に呼び出さない場合、トランザクションがコミットされたときにのみ呼び出されます。したがって、挿入ステートメントは実際には2以降のDBに対して実行され、それまでに例外がスローされます。

于 2012-12-17T16:25:58.003 に答える