3

Spring@Transactionalアノテーションと永続化について誤解しています。JPAとHibernateでSpring 3.1を使用しています。永続化とはエンティティを永続化コンテキストに追加することを意味し(ただし、コミットまたはフラッシュするまでクエリを実行しないでください)、@Transactionalアノテーションはメソッドをトランザクションでラップすることを意味すると思いました。

ただし、この短い例では、実行ポインターが永続に達すると、name を null にすることはできない (db 制約) ため、例外で失敗します。

import javax.persistence.EntityManager;

@PersistenceContext
private EntityManager entityManager;

@Transactional
public void test() {
    Brand brand = new Brand();
    entityManager.persist(brand);
    brand.setName("test");
}

と を交換するsetName()persist()、すべてが機能します。ただし、メソッドの最後にクエリが作成されて実行されると思っていたので、なぜ逆にそうでないのかわかりません。

誰か説明してくれませんか?

4

3 に答える 3

4

JPA では、オブジェクトが persist() に渡されると、「管理対象」になります。これは、管理対象になる JPA 実装の一部として、永続オブジェクトの ID を生成する必要があるためです。

ID 生成が自動インクリメント (GenerationType.IDENTITY) に基づいている場合、データベースに挿入ステートメントを発行して、キーを取得して割り当てる必要があります。ID 生成がシーケンス/テーブルに基づく場合、ID は JPA 実装管理 ID プールによって管理および割り当てられます。この場合、ストレート挿入は必須ではありません。

オブジェクトが persist() に渡されて管理されるようになると、永続フィールドに対する変更は、トランザクションの時点でデータベースにフラッシュする必要があります。あなたの場合、ID生成がIdentityの場合、挿入の後に更新が必要です。ID 生成が他の方法である場合は、単一の挿入ステートメントで十分です。トランザクションがロールバックされた場合、SQL はデータベースに送信されません。

これはBatoo JPAでの実装です。

これが理にかなっていることを願っています。

于 2012-10-05T18:32:32.090 に答える
2

トランザクションアノテーションのおかげで、メソッドの最後にコミットされます。ただし、新しいレコードはpersistで作成され、例外がスローされる可能性があります。

メソッドが終了する前でも、ロールバックできます。私は通常、例外のためにロールバックで注釈を付けます。

于 2012-10-05T16:03:26.733 に答える
0

持続は「挿入」クエリを実行します。トランザクション アノテーションはトランザクションを開始するためのものであり、例外が発生した場合はトランザクションをロールバックします。

于 2012-10-05T16:04:07.530 に答える