web-dev-qa-db-ja.com

更新メソッドを呼び出さずにトランザクションを保存

@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がデータベースに永続化されるのですか?

38
John LaFleur

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

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

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

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

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

57
meriton

JPAを使用している場合、仕様では、エンティティが管理状態(およびアクティブトランザクション内でDAOからデータを取得することで行われる)であれば、すべての変更が行われると記載されていますトランザクションコミットの間にデータベースに反映されます。

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

7
Piotr Nowicki

@Transactional(readOnly = true)を使用して解決しました

1
Sandy

データベースの自動更新を防止することは、2段階のプロセスです。

ステップI::

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

ステップII:

getSession().clear(); //This will actually discard all changes
1
Sagar Kapadia

JPAの場合、entityManager.detach(entity)を呼び出して自動フラッシュを回避します。ただし、切り離されたエンティティはORMマジックを失います。遅延フェッチ、カスケード更新。

0
Hank