データベースからメンバーレコードを削除することを想定して、このメソッドを以下に記述しました。しかし、サーブレットで使用するとエラーが返されます。
MemberDaoクラス
public static void deleteMember(Member member) {
Session hibernateSession = HibernateUtil.getSessionFactory().getCurrentSession();
Transaction tx = hibernateSession.beginTransaction();
hibernateSession.delete(member);
tx.commit();
}
コントローラーパーツ
if(delete != null) {
HttpSession httpSession = request.getSession();
Member member = (Member) httpSession.getAttribute("member");
MemberDao.deleteMember(member);
nextPage = "ledenlijst.jsp";
}
HTTPステータス5
org.hibernate.StaleStateException: Batch update returned unexpected row count from update [0]; actual row count: 0; expected: 1
ページを複数回実行しようとすると、このエラーがスローされることもあります。
org.hibernate.exception.GenericJDBCException: Could not execute JDBC batch update
誰がこれらのエラーの原因を正確に知っていますか?
このエラーはいくつかの原因で発生する可能性があります。私はそれを信用していない、それを見つけた ここ 。
- オブジェクトをコミットする前にデータをフラッシュすると、保留中のすべてのオブジェクトがクリアされる場合があります。
- オブジェクトに自動生成される主キーがあり、割り当てられたキーを強制している場合
- オブジェクトをデータベースにコミットする前にオブジェクトをクリーニングする場合。
- ゼロまたは不正なID:IDをゼロまたは他の何かに設定すると、Hibernateは挿入ではなく更新を試みます。
- オブジェクトは古い:Hibernateはセッションからオブジェクトをキャッシュします。オブジェクトが変更され、Hibernateがそれを知らない場合、この例外をスローします— StaleStateExceptionに注意してください
この答え by beny2 も見てください。これにより、問題を見つけるためのヒントがさらに得られます。
- Hibernate構成で、hibernate.show_sqlをtrueに設定します。これにより、実行され、問題の原因となっているSQLが表示されます。
- SpringおよびHibernateのログレベルをDEBUGに設定します。これにより、どの行が問題を引き起こしているかをよりよく理解できます。
- Springでトランザクションマネージャーを構成せずに問題を再現する単体テストを作成します。これにより、問題のあるコード行のより良いアイデアが得られるはずです。
例外 org.hibernate.StaleStateException: Batch update returned unexpected row count from update [0]; actual row count: 0; expected: 1
は、Hibernateがデータベースにフラッシュしたいエンティティがトランザクションの開始時と正確に一致していないことに気付いたときにスローされるために使用します。
私に起こる2つの異なるユースケースをより詳細に説明しました ここ 。
私の場合、この例外はエンティティマッピングの誤りが原因でした。リレーションのカスケードがなく、参照された子エンティティは、親から参照しようとする前に保存されませんでした。に変更する
@OneToMany(cascade = CascadeType.ALL)
問題を修正しました。
この例外の原因を見つける最善の方法は、ログのshow_sqlおよびDEBUGレベルを設定することです。問題を引き起こしたSQLで停止します。
Memcachedをセカンダリキャッシュとして使用しているときに、hibernate/JPA 2.1でも同じ問題が発生しました。 StaleStateExceptionとともに上記の例外が発生します。解像度は、以前に指摘されたものとは異なりました。
同じテーブルとトランザクション内で削除と選択(検索)をインターリーブする操作がある場合、休止状態が圧倒され、その古い状態の例外を報告することがあります。異なるエンティティに対する複数の同一の操作が同じテーブルで発生するため、本番環境でのみ発生します。システムのタイムアウトとトスの例外が表示されます。
解決策は、単により効率的にすることです。ループでインターリーブするのではなく、読み取りが必要なアイテムを解決して、できれば1回の操作で読み取ってください。次に、別の操作で削除を実行します。繰り返しますが、すべて同じトランザクション内にありますが、読み取り/削除/読み取り/削除操作を休止状態にしないでください。
これははるかに高速で、Hibernateのハウスキーピングの負荷を大幅に削減します。問題はなくなりました。これは、2次キャッシュを使用している場合に発生し、2次キャッシュなしで解決するためにデータベースに負荷がかかるため発生しません。それは別の問題です。
これは私の場合の解決策であり、おそらくあなたに役立つでしょう!
実際には、データベースフィールドタイプ(postgreSQLのタイムスタンプ)とhibernate xmlファイルの同等のプロパティタイプ(カレンダー)の間の変換の問題でした。 Hibernateがこの更新リクエストを行ったとき、そのリクエストは不正な変換カレンダー値で問い合わせるため、行を取得しませんでした。そのため、Hibernate xmlファイルの「Date」のプロパティタイプ「Calendar」を置き換えるだけで、問題は修正されました。
私は同じ問題に直面していました。コードはテスト環境で機能していました。しかし、ステージング環境では機能していませんでした。
org.hibernate.jdbc.BatchedTooManyRowsAffectedException: Batch update returned unexpected row count from update [0]; actual row count: 3; expected: 1
問題は、テーブルのテストDBテーブルの各プライマリキーに1つのエントリがあったことです。ただし、ステージングDBには、同じプライマリキーに対して複数のエントリがありました。 (問題はステージングDBにあり、テーブルには主キー制約がなく、複数のエントリがありました。)
そのため、更新操作のたびに失敗します。単一のレコードを更新しようとし、更新カウントを1として取得しようとします。ただし、同じ主キーのテーブルに3つのレコードがあるため、結果更新カウントは3になります。予想更新カウントと実際の結果更新カウントが一致しなかったため、例外をスローしてロールバックします。
重複した主キーを持つすべてのレコードを削除し、主キー制約を追加した後。正常に動作しています。
私は最近これを経験しましたが、何が起こったのかは、更新メソッドを使用し、既存のレコードがなかったために例外をスローしていたことです。メソッドをsaveOrUpdateに変更しました。出来た。
私はこの問題を抱えていました、
コードを確認しましたが、問題はありませんでしたが、データを確認したところ、同じIDの2つのエンティティが見つかりました!
したがって、flush()
は、バッチ更新で1つずつ機能し、2つの行を見つけたため、機能しませんでした。したがって、更新されず、例外がスローされましたが、それは私の問題でした。それがあなたのためにうまくいくかどうかはわかりません!