1

Hibernate の delete メソッドを使用してオブジェクトを削除しようとしていますが、StaleStateException 例外が発生します。私の要件は、一意のキーに基づいてオブジェクトを削除することなので、このために私は何かをしています。

String queryString="from Destination destination "+
                                                   "where destination.destinationID = :destinationid";
    tx.begin();
                Query query= session.createQuery(queryString).setParameter("destinationid", destinationId, Hibernate.STRING);
               @SuppressWarnings("unchecked")
               List<Destination> list=query.list();
               Destination ds=list.get(0);
                 if(!list.isEmpty())
                  session.evict(ds);
                  session.delete(ds);

                  tx.commit();

リストが空でない場合、リストには要素が1つしかないことがわかっているので、リストから最初の要素のみをフェッチします(これが良いアプローチかどうかはわかりません)

しかし、このメソッドを実行していると、コンソールに次のSQLログが表示されます

Hibernate: 
    /* delete collection AirTransport.timeTable */ delete 
        from
            tr.TRANSPORTTIME 
        where
            TRANSPORTID=?
Hibernate: 
    /* delete collection AirTransport.timeTable */ delete 
        from
            tr.TRANSPORTTIME 
        where
            TRANSPORTID=?
Hibernate: 
    /* delete collection AirTransport.timeTable */ delete 
        from
            tr.TRANSPORTTIME 
        where
            TRANSPORTID=?
Hibernate: 
    /* delete collection RoadTransport.timeTable */ delete 
        from
            tr.TRANSPORTTIME 
        where
            TRANSPORTID=?
Hibernate: 
    /* delete collection TrainTransport.timeTable */ delete 
        from
            tr.TRANSPORTTIME 
        where
            TRANSPORTID=?
Hibernate: 
    /* delete AirTransport */ delete 
        from
            tr.TRANSPORT 
        where
            UUID=?
Hibernate: 
    /* delete AirTransport */ delete 
        from
            tr.TRANSPORT 
        where
            UUID=?
Hibernate: 
    /* delete AirTransport */ delete 
        from
            tr.TRANSPORT 
        where
            UUID=?
Hibernate: 
    /* delete RoadTransport */ delete 
        from
            tr.TRANSPORT 
        where
            UUID=?

そしてその投げるよりも

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:61)
 at org.hibernate.jdbc.Expectations$BasicExpectation.verifyOutcome(Expectations.java:46)

私が疑わしいのは、Transport テーブルに AirTransport 用に 1 つ、Train 用に 1 つ、Road 用に 1 つだけの 3 つのエントリがあり、TransPortTime テーブルには 3 つのエントリがあり、Transport タイプごとに 1 つと、

3つのトランスポートクラスすべての複合要素としてTransportTimeを使用しています

<set name="timeTable" table="TRANSPORTTIME" lazy="true">
                        <key column="TRANSPORTID"/>
                        <composite-element
                                class="TransportTime">

                                <property name="deperatureTime" type="java.util.Date">
                                        <column name="DEPERATURETIME" />
                                </property>
                                <property name="arrivalTime" type="java.util.Date">
                                        <column name="ARRIVALTIME" />
                                </property>
                                <other properties>
                        </composite-element>

                </set>

私はまだ何がうまくいかないのか理解できないので、コミュニティで尋ねても


追加情報を追加するだけです。宛先クラスには、3 つのそれぞれの trabsport クラスの以下のマッピングがあります。

<set name="airTransport" table="AIRTRANSPORT" inverse="true" lazy="true" cascade="save-update, delete">
        <key>
            <column name="DESTINATIONID" />
        </key>
        <one-to-many class="AirTransport" />
    </set>
    <set name="roadTransport" table="ROADTRANSPORT" inverse="true" lazy="true" cascade="save-update, delete">
        <key>
            <column name="DESTINATIONID" />
        </key>
        <one-to-many class="RoadTransport" />
    </set>
    <set name="trainTransport" table="TRAINTRANSPORT" inverse="true" lazy="true" cascade="save-update, delete">
        <key>
            <column name="DESTINATIONID" />
        </key>
        <one-to-many class="TrainTransport" />
    </set>

私のRoadTransport/Train/Air Transportには次のマッピングがあります

<class name="AirTransport" table="TRANSPORT">
        <id name="uuid" type="java.lang.String">
            <column name="UUID" />
            <generator class="uuid"/>
        </id>
        <many-to-one name="destination" class="Destination" fetch="join">
            <column name="DESTINATIONID" />
        </many-to-one>
       <property mappings>
        <set name="timeTable" table="TRANSPORTTIME" lazy="true">
            <key column="TRANSPORTID"/>
            <composite-element
                class="TransportTime">
                <property mappings>
                </composite-element>

        </set>
    </class>

他の 2 つのマッピング ファイルも同一であるため、これら 3 つのクラスのマッピング関連付けを親クラスから削除すると、削除機能が完全に機能し始めました。

つまり、TimeTable クラスを Transport クラス (Air/Train/Road Transport クラス) 内のコンポーネントとしてマッピングする際に根本的に間違っていることを意味します。

この点に関する提案は非常に役立ちます

4

2 に答える 2

3

StaleStateException は、バージョン番号またはタイムスタンプのチェックが失敗した場合にスローされ、Session に古いデータが含まれていることを示します (バージョン管理で長いトランザクションを使用している場合)。存在しない行を削除または更新しようとした場合にも発生します。

この例外は、多くの場合、ユーザーがクラスに対して正しい unsaved-value 戦略を指定できなかったことを示していることに注意してください!

http://www.dil.univ-mrs.fr/~massat/docs/hibernate-3.1/api/org/hibernate/StaleStateException.html

私の推測では、この長いトランザクション中に行が更新されます。そして、削除をコミットしようとすると、バージョンが異なることがわかります (セッション内の削除済みとしてマークされたものと、db 内の実際の行) ため、StaleStateException がスローされます。

uniqueResult()また、クエリクラスには、実行するたびに1つの結果を返すことが確実な場合、1つのオブジェクト結果を返すメソッドが呼び出される必要があります。これにより、リスト パーツの 0 番目のインデックスを取得しようとするコードを節約できます。

于 2011-01-18T15:36:55.820 に答える
1

あなたのコードは、(少なくとも) 2 つの点で間違っています。

  • isEmpty()0番目のアイテムを取得する前に確認する必要があります。そうしないと、例外が発生する危険があります
  • 削除する前に追い出すべきではありません。evict()行を取り除く

また、返される行数を改ざんするデータベース トリガーがないことも確認してください。

于 2011-01-18T11:46:24.783 に答える