60

@Transactionalで注釈が付けられたメソッドがあります。Oracle DBからオブジェクトを取得し、フィールドを変更してから、メソッドから戻ります。オブジェクトを保存するのを忘れましたが、データベースがとにかく更新されることを発見しました。

applicationContext

<tx:annotation-driven />
<bean id="transactionManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager">
    <property name="sessionFactory" ref="sessionFactory" />
</bean>

私の方法

@Transactional
public void myMethod(long id) {
    MyObject myObj = dao.getMstAttributeById(id);
    myObj.setName("new name");
    //dao.update(myObj);
}

私の質問は、なぜMyObjectがデータベースに永続化されるのですか?

4

5 に答える 5

76

hibernateは永続エンティティに加えられた変更を自動的に検出し、それに応じてデータベースを更新するためです。この動作は、Hibernateリファレンスマニュアルの第11章に記載されています。関連する部分は次のとおりです。

Hibernateは、次のオブジェクト状態を定義およびサポートします。

  • 一時的-オブジェクトがnew演算子を使用してインスタンス化されたばかりで、Hibernateセッションに関連付けられていない場合、オブジェクトは一時的です。データベースに永続的な表現がなく、識別子の値が割り当てられていません。アプリケーションが参照を保持しなくなった場合、一時インスタンスはガベージコレクターによって破棄されます。Hibernateセッションを使用してオブジェクトを永続化します(そして、この移行のために実行する必要のあるSQLステートメントをHibernateに処理させます)。

  • 永続的-永続的なインスタンスには、データベース内の表現と識別子の値があります。保存またはロードされたばかりの場合もありますが、定義上、セッションのスコープ内にあります。Hibernateは、永続状態のオブジェクトに加えられた変更を検出し、作業単位が完了するとその状態をデータベースと同期します。開発者は、オブジェクトを一時的にする必要がある場合、手動のUPDATEステートメントやDELETEステートメントを実行しません。

  • デタッチ-デタッチされたインスタンスは永続化されたオブジェクトですが、そのセッションは閉じられています。もちろん、オブジェクトへの参照は引き続き有効であり、デタッチされたインスタンスはこの状態で変更される可能性もあります。デタッチされたインスタンスは、後で新しいセッションに再アタッチして、そのインスタンス(およびすべての変更)を再び永続化することができます。この機能により、ユーザーの思考時間を必要とする長時間実行ユニットのプログラミングモデルが可能になります。これらをアプリケーショントランザクション、つまりユーザーの観点から見た作業単位と呼びます。

于 2011-11-19T00:51:02.970 に答える
14

JPAを使用している場合、仕様では、エンティティが管理された状態にある場合(これは、アクティブなトランザクション内でDAOからデータをフェッチすることによって行うことです)、それに加えられたすべての変更は、トランザクションコミット中のデータベース。

つまり、トランザクションのコミットによってデータベースへの変更がフラッシュされるため、更新操作を呼び出すかどうかは実際には問題ではありません。

于 2011-11-19T00:47:24.937 に答える
6

私は@Transactional(readOnly = true)それを解決するために使用しました

于 2019-02-12T07:51:16.397 に答える
4

データベースの自動更新を防ぐことは2段階のプロセスであることがわかりました。

ステップI::

getSession().setFlushMode(FlushMode.MANUAL) // [FlushMode.NEVER is depracated in 4.x]

ステップII:

getSession().clear(); //This will actually discard all changes
于 2014-04-10T09:46:51.353 に答える
2

JPAの場合は、entityManager.detach(entity)自動フラッシュを回避するために呼び出します。ただし、デタッチされたエンティティは、遅延フェッチ、カスケード更新などの後でORMマジックを失うことに注意する必要があります。

于 2019-03-20T10:02:43.640 に答える