0

FooBarの 2 つのクラスがあるとします。Fooには、次のようにマッピングされたBarへの多対 1 の関連付けがあります。

<many-to-one name="bar" class="Bar" lazy="false" fetch="join" >
    <column name="BAR_ID" sql-type="INTEGER" />
</many-to-one>

EmptyInterceptorから拡張し、次のようにonSaveメソッドをオーバーライドするカスタム インターセプターを作成しました。

public boolean onSave(Object entity, Serializable id, Object[] state,
        String[] propertyNames, Type[] types) {
    boolean modified = false;

    if(entity instanceof Foo) {
        Bar bar = new Bar();

        //do some initialization stuff to bar

        for(int i = 0; i < propertyNames.length; i++) {
             if("bar".equals(propertyNames[i])) {
                 state[i] = bar;
                 modified = true;
                 break;
             } 
        }

        //This code essentially gets the current hibernate session and calls save on
        //the passed object.
        BarDAO barDao = BarDAO.INSTANCE;
        barDAO.save(bar);
    }

    return modified;
} 

問題は、bar に対して SQL の挿入ステートメントが実行されますが、挿入前に変更された Foo であるエンティティ オブジェクトに対して SQL の更新ステートメントが実行されることです。これにより、次の Hibernate 例外が発生します。

最後の原因: バッチ更新が更新 [0] から予期しない行数を返しました。実際の行数: 0; 予想: 1

バー オブジェクトを保存しないと、期待どおりに SQL 挿入ステートメントが実行されます。

何がうまくいかなかったのかについての洞察はありますか?

前もって感謝します。

4

1 に答える 1

0

インターセプターのonFlushDirtyメソッドでcurrentState配列を更新する必要があると思います。

onLoadおよびonFlushDirtyメソッドでオブジェクトを変更していたため、同様の問題がありました。問題は、オブジェクトの以前の状態がonLoadメソッドの結果であると hibernate が考えており、update ステートメントがそれらの値を使用して db テーブル内の行を見つけようとしていたことです。onSaveメソッドで状態を変更しているため、同じ問題が発生する可能性があります。

于 2013-06-06T15:47:25.447 に答える