質問

Hibernateには、オブジェクトを取得してデータベースに格納するメソッドがいくつかあります。それらの違いは何ですか、どれを使用するか、なぜ何を使用するかを知っているインテリジェントなメソッドが1つだけではないのはなぜですか?

これまでに特定したメソッドは次のとおりです。

  • save()
  • update()
  • saveOrUpdate()
  • saveOrUpdateCopy()
  • merge()
  • persist()
役に立ちましたか?

解決

メソッドについての私の理解です。これらは主に API に基づいていますこれらのすべてを実際に使用しないでください。

saveOrUpdate いくつかのチェックに応じて、保存または更新の呼び出し。例えば。識別子が存在しない場合、saveが呼び出されます。それ以外の場合、更新が呼び出されます。

保存 エンティティを永続化します。存在しない場合は識別子を割り当てます。もしそうなら、それは本質的に更新を行っています。生成されたエンティティのIDを返します。

更新 既存の識別子を使用してエンティティを永続化しようとします。識別子が存在しない場合、例外がスローされると思います。

saveOrUpdateCopy これは非推奨であり、使用しないでください。代わりに...

マージ 今、私の知識が揺らぎ始める場所です。ここで重要なのは、一時的なエンティティ、分離されたエンティティ、永続的なエンティティの違いです。オブジェクトの状態の詳細については、ご覧くださいここ。保存して&更新、永続オブジェクトを扱っています。これらはセッションにリンクされているため、Hibernateは何が変更されたかを認識します。しかし、一時オブジェクトがある場合、セッションは関係しません。これらの場合、更新のためにマージを使用し、保存のために持続する必要があります。

持続 前述のように、これは一時オブジェクトで使用されます。生成されたIDは返されません。

他のヒント

╔══════════════╦═══════════════════════════════╦════════════════════════════════╗
║    METHOD    ║            TRANSIENT          ║            DETACHED            ║
╠══════════════╬═══════════════════════════════╬════════════════════════════════╣
║              ║       sets id if doesn't      ║   sets new id even if object   ║
║    save()    ║     exist, persists to db,    ║    already has it, persists    ║
║              ║    returns attached object    ║ to DB, returns attached object ║
╠══════════════╬═══════════════════════════════╬════════════════════════════════╣
║              ║       sets id on object       ║             throws             ║
║   persist()  ║     persists object to DB     ║       PersistenceException     ║
║              ║                               ║                                ║
╠══════════════╬═══════════════════════════════╬════════════════════════════════╣
║              ║                               ║                                ║
║   update()   ║           Exception           ║     persists and reattaches    ║
║              ║                               ║                                ║
╠══════════════╬═══════════════════════════════╬════════════════════════════════╣
║              ║  copy the state of object in  ║    copy the state of obj in    ║
║    merge()   ║     DB, doesn't attach it,    ║      DB, doesn't attach it,    ║
║              ║    returns attached object    ║     returns attached object    ║
╠══════════════╬═══════════════════════════════╬════════════════════════════════╣
║              ║                               ║                                ║
║saveOrUpdate()║           as save()           ║            as update()         ║
║              ║                               ║                                ║
╚══════════════╩═══════════════════════════════╩════════════════════════════════╝
  • Hibernate Forum をご覧ください。永続化と保存の微妙な違いの説明。違いは、INSERTステートメントが最終的に実行される時間であるように見えます。 save は識別子を返すため、トランザクションの状態に関係なくINSERTステートメントを即座に実行する必要があります(これは一般に悪いことです)。 Persist は、識別子を割り当てるためだけに、現在実行中のトランザクション以外のステートメントを実行しません。 Save / Persistは両方とも transientインスタンスで機能します。つまり、まだ識別子が割り当てられていないため、DBに保存されません。

  • 更新マージの両方が、デタッチされたインスタンス、つまり、DBに対応するエントリがあるが現在存在するインスタンスで動作しますセッションに接続されていない(またはセッションによって管理されていない)。それらの違いは、関数に渡されるインスタンスに何が起こるかです。 update はインスタンスを再接続しようとします。つまり、現在セッションに接続されている永続エンティティの他のインスタンスが存在しない可能性があり、そうでない場合は例外がスローされます。ただし、 merge は、すべての値をSessionの永続インスタンスにコピーします(現在読み込まれていない場合は読み込まれます)。入力オブジェクトは変更されません。したがって、マージ更新よりも一般的ですが、より多くのリソースを使用する可能性があります。

このリンクは良い方法で説明しています:

http://www.stevideter.com/2008/12/ 07 / saveorupdate-versus-merge-in-hibernate /

私たちは皆、これらの問題にまれにしか遭遇しないので、それらをもう一度見ると、これを解決したことがわかりますが、どのように覚えていないのかわかりません。

HibernateでSession.saveOrUpdate()を使用するときにスローされるNonUniqueObjectExceptionは私のものの1つです。複雑なアプリケーションに新しい機能を追加します。私のユニットテストはすべてうまくいきます。次に、UIをテストしてオブジェクトを保存しようとすると、メッセージで例外が発生し始めます“同じ識別子値を持つ別のオブジェクトが既にセッションに関連付けられています。”これは、Java Persistence with Hibernateのサンプルコードです。

            Session session = sessionFactory1.openSession();
            Transaction tx = session.beginTransaction();
            Item item = (Item) session.get(Item.class, new Long(1234));
            tx.commit();
            session.close(); // end of first session, item is detached

            item.getId(); // The database identity is "1234"
            item.setDescription("my new description");
            Session session2 = sessionFactory.openSession();
            Transaction tx2 = session2.beginTransaction();
            Item item2 = (Item) session2.get(Item.class, new Long(1234));
            session2.update(item); // Throws NonUniqueObjectException
            tx2.commit();
            session2.close();

この例外の原因を理解するには、デタッチされたオブジェクトと、デタッチされたオブジェクトでsaveOrUpdate()(または単にupdate())を呼び出したときに何が起こるかを理解することが重要です。

個々のHibernateセッションを閉じると、作業している永続オブジェクトは切り離されます。つまり、データはまだアプリケーションのメモリにありますが、Hibernateはオブジェクトの変更を追跡する責任を負いません。

その後、デタッチされたオブジェクトを変更して更新する場合は、オブジェクトを再アタッチする必要があります。その再接続プロセス中に、Hibernateは同じオブジェクトの他のコピーがあるかどうかを確認します。見つかった場合は、“実際の”コピーはもうありません。保存する予定の他のコピーに他の変更が加えられた可能性がありますが、Hibernateはそれらを管理していなかったため、それらについては知りません。

不正なデータを保存するのではなく、HibernateはNonUniqueObjectExceptionを介して問題について通知します。

だから私たちは何をすべきか? Hibernate 3にはmerge()があります(Hibernate 2にはsaveOrUpdateCopy()を使用します)。このメソッドは、Hibernateが他のデタッチされたインスタンスから保存したいインスタンスに変更を強制的にコピーするため、保存する前にメモリ内のすべての変更をマージします。

        Session session = sessionFactory1.openSession();
        Transaction tx = session.beginTransaction();
        Item item = (Item) session.get(Item.class, new Long(1234));
        tx.commit();
        session.close(); // end of first session, item is detached

        item.getId(); // The database identity is "1234"
        item.setDescription("my new description");
        Session session2 = sessionFactory.openSession();
        Transaction tx2 = session2.beginTransaction();
        Item item2 = (Item) session2.get(Item.class, new Long(1234));
        Item item3 = session2.merge(item); // Success!
        tx2.commit();
        session2.close();

マージは、インスタンスの新しく更新されたバージョンへの参照を返すことに注意することが重要です。セッションにアイテムを再添付することはありません。インスタンスの等価性(item == item3)をテストすると、この場合falseを返すことがわかります。おそらく、この時点からitem3を使用したいと思うでしょう。

また、Java Persistence API(JPA)には、オブジェクトの切り離しおよび再接続の概念がなく、EntityManager.persist()およびEntityManager.merge()を使用することに注意することも重要です。

p>

私は一般に、Hibernateを使用する場合、saveOrUpdate()が通常私のニーズに十分であることを発見しました。通常、同じタイプのオブジェクトへの参照を持つオブジェクトがある場合にのみ、マージを使用する必要があります。ごく最近、例外の原因は、参照が再帰的ではなかったことを検証するコードにありました。検証の一部として同じオブジェクトをセッションにロードしていたため、エラーが発生しました。

この問題はどこで発生しましたか?マージはうまくいきましたか、または別のソリューションが必要でしたか?常にマージを使用しますか、それとも特定のケースに必要な場合にのみ使用しますか

実際、hibernateの save()メソッドと persist()メソッドの違いは、使用しているジェネレータークラスによって異なります。

ジェネレータクラスが割り当てられている場合、 save()メソッドと persist()メソッドに違いはありません。ジェネレータ‘ assigned’つまり、プログラマーとして、データベースに保存する主キー値を指定する必要があります[このジェネレーターの概念を知ってほしい] 割り当てられたジェネレータークラス以外の場合、ジェネレータークラス名がIncrementである場合、hibernateはプライマリキーid値をデータベース右に割り当てます[割り当てられたジェネレーター以外、hibernateはプライマリキーid値を管理するためにのみ使用されます]、この場合、 save()または persist()メソッドを呼び出すと、通常どおりデータベースにレコードが挿入されます ただし、 save()メソッドは、hibernateによって生成されたプライマリキーID値を返すことができ、

で確認できます。
long s = session.save(k);

同じ場合、 persist()はクライアントに値を返しません。

すべてのhibernate saveメソッドの違いを示す良い例を見つけました:

http:// www。 journaldev.com/3481/hibernate-session-merge-vs-update-save-saveorupdate-persist-example

簡単に言えば、上記のリンクによると:

save()

  • トランザクションの外部でこのメソッドを呼び出すことができます。トランザクションなしでこれを使用し、エンティティ間でカスケードしている場合、セッションをフラッシュしない限り、プライマリエンティティのみが保存されます。
  • したがって、プライマリオブジェクトからマップされた他のオブジェクトがある場合、それらはトランザクションのコミット時またはセッションのフラッシュ時に保存されます。

persist()

  • トランザクションでsave()を使用するのと似ているため、安全でカスケードされたオブジェクトを処理します。

saveOrUpdate()

  • トランザクションの有無にかかわらず使用できます。save()と同様に、トランザクションなしで使用した場合、マッピングされたエンティティは保存されません。セッションをフラッシュします。

  • 提供されたデータに基づいて、挿入または更新クエリへの結果。データベースにデータが存在する場合、更新クエリが実行されます。

update()

  • エンティティ情報のみを更新していることがわかっている場合は、Hibernate updateを使用する必要があります。この操作により、エンティティオブジェクトが永続的なコンテキストに追加され、トランザクションがコミットされたときにさらに変更が追跡され、保存されます。
  • したがって、updateを呼び出した後でも、エンティティに値を設定すると、トランザクションがコミットされると値が更新されます。

merge()

  • Hibernate mergeは既存の値を更新するために使用できますが、このメソッドは渡されたエンティティオブジェクトからコピーを作成して返します。返されたオブジェクトは永続コンテキストの一部であり、変更が追跡され、渡されたオブジェクトは追跡されません。これは、他のすべてのメソッドとのmerge()の大きな違いです。

これらすべての実用的な例についても、上記のリンクを参照してください。これらのすべての異なる方法の例を示しています。

デタッチされたオブジェクトで更新を呼び出すと、オブジェクトを変更したかどうかに関係なく、データベースで常に更新が行われることに注意してください。希望どおりでない場合は、LockMode.NoneでSession.lock()を使用する必要があります。

現在のセッションの範囲外でオブジェクトが変更された場合にのみ、updateを呼び出す必要があります(デタッチモードの場合)。

この記事で説明したように、ほとんどの場合はJPAメソッドを優先し、バッチ処理タスクの場合は update を優先する必要があります。

JPAまたはHibernateエンティティは、次の4つの状態のいずれかになります。

  • 一時的(新規)
  • 管理(永続)
  • 分離
  • 削除(削除)

1つの状態から別の状態への遷移は、EntityManagerまたはSessionメソッドを介して行われます。

たとえば、JPA EntityManager は、次のエンティティ状態遷移メソッドを提供します。

ここに画像の説明を入力してください

Hibernate Session は、すべてのJPA EntityManager メソッドを実装し、 save saveOrUpdate および update

ここに画像の説明を入力してください

持続

エンティティの状態をTransient(New)からManaged(Persisted)に変更するには、JPA EntityManager が提供する persist メソッドを使用します。 Hibernate Session によって。

  

persist メソッドは、 DefaultPersistEventListener Hibernateイベントリスナーによって処理される PersistEvent をトリガーします。

したがって、次のテストケースを実行する場合:

doInJPA(entityManager -> {
    Book book = new Book()
    .setIsbn("978-9730228236")
    .setTitle("High-Performance Java Persistence")
    .setAuthor("Vlad Mihalcea");

    entityManager.persist(book);

    LOGGER.info(
        "Persisting the Book entity with the id: {}", 
        book.getId()
    );
});

Hibernateは次のSQLステートメントを生成します。

CALL NEXT VALUE FOR hibernate_sequence

-- Persisting the Book entity with the id: 1

INSERT INTO book (
    author, 
    isbn, 
    title, 
    id
) 
VALUES (
    'Vlad Mihalcea', 
    '978-9730228236', 
    'High-Performance Java Persistence', 
    1
)

id は、 Book エンティティを現在の永続コンテキストにアタッチする前に割り当てられることに注意してください。管理エンティティは Map 構造に格納され、キーはエンティティタイプとその識別子で形成され、値はエンティティ参照であるため、これが必要です。これが、JPA EntityManager とHibernate Session がFirst-Level Cacheとして知られている理由です。

persist を呼び出すと、エンティティは現在実行中の永続コンテキストにのみ接続され、 flush が呼び出されるまでINSERTを延期できます。

唯一の例外は IDENTITYジェネレーターです。エンティティ識別子を取得できる唯一の方法であるため、すぐにINSERTをトリガーします。このため、HibernateはIDENTITYジェネレーターを使用してエンティティの挿入をバッチ処理できません。このトピックの詳細については、この記事をご覧ください。

保存

Hibernate固有の save メソッドはJPAよりも前のバージョンであり、Hibernateプロジェクトの開始以来利用可能です。

  

save メソッドは、 DefaultSaveOrUpdateEventListener Hibernateイベントリスナーによって処理される SaveOrUpdateEvent をトリガーします。したがって、 save メソッドは、 update および saveOrUpdate メソッドと同等です。

save メソッドの動作を確認するには、次のテストケースを検討してください。

doInJPA(entityManager -> {
    Book book = new Book()
    .setIsbn("978-9730228236")
    .setTitle("High-Performance Java Persistence")
    .setAuthor("Vlad Mihalcea");

    Session session = entityManager.unwrap(Session.class);

    Long id = (Long) session.save(book);

    LOGGER.info(
        "Saving the Book entity with the id: {}", 
        id
    );
});

上記のテストケースを実行すると、Hibernateは次のSQLステートメントを生成します。

CALL NEXT VALUE FOR hibernate_sequence

-- Saving the Book entity with the id: 1

INSERT INTO book (
    author, 
    isbn, 
    title, 
    id
) 
VALUES (
    'Vlad Mihalcea', 
    '978-9730228236', 
    'High-Performance Java Persistence', 
    1
)

ご覧のとおり、結果は persist メソッド呼び出しと同じです。ただし、 persist とは異なり、 save メソッドはエンティティ識別子を返します。

詳細については、out この記事

更新

Hibernate固有の update メソッドは、ダーティチェックメカニズムを使用して、フラッシュ時にエンティティを強制的に更新します。

  

update メソッドは、 DefaultSaveOrUpdateEventListener Hibernateイベントリスナーによって処理される SaveOrUpdateEvent をトリガーします。したがって、 update メソッドは save および saveOrUpdate メソッドと同等です。

update メソッドがどのように機能するかを確認するには、1つのトランザクションで Book エンティティを永続化し、エンティティが切り離された状態にある間にエンティティを変更する次の例を考えます。また、 update メソッド呼び出しを使用してSQL UPDATEを強制します。

Book _book = doInJPA(entityManager -> {
    Book book = new Book()
    .setIsbn("978-9730228236")
    .setTitle("High-Performance Java Persistence")
    .setAuthor("Vlad Mihalcea");

    entityManager.persist(book);

    return book;
});

LOGGER.info("Modifying the Book entity");

_book.setTitle(
    "High-Performance Java Persistence, 2nd edition"
);

doInJPA(entityManager -> {
    Session session = entityManager.unwrap(Session.class);

    session.update(_book);

    LOGGER.info("Updating the Book entity");
});

上記のテストケースを実行すると、Hibernateは次のSQLステートメントを生成します。

CALL NEXT VALUE FOR hibernate_sequence

INSERT INTO book (
    author, 
    isbn, 
    title, 
    id
) 
VALUES (
    'Vlad Mihalcea', 
    '978-9730228236', 
    'High-Performance Java Persistence', 
    1
)

-- Modifying the Book entity
-- Updating the Book entity

UPDATE 
    book 
SET 
    author = 'Vlad Mihalcea', 
    isbn = '978-9730228236', 
    title = 'High-Performance Java Persistence, 2nd edition'
WHERE 
    id = 1

UPDATE は永続コンテキストのフラッシュ中に、コミットの直前に実行されることに注意してください。そのため、 Updating the Book entity メッセージが最初に記録されます。

@SelectBeforeUpdate を使用して不要な更新を回避する

現在、エンティティが切り離された状態で変更されていない場合でも、UPDATEは常に実行されます。これを防ぐために、 @SelectBeforeUpdate Hibernateアノテーションを使用して、 loaded を取得した SELECT ステートメントをトリガーできます。確認メカニズム。

したがって、 BookSelectエンティティに @SelectBeforeUpdate アノテーションを付けた場合:

@Entity(name = "Book")
@Table(name = "book")
@SelectBeforeUpdate
public class Book {

    //Code omitted for brevity
}

次のテストケースを実行します。

Book _book = doInJPA(entityManager -> {
    Book book = new Book()
    .setIsbn("978-9730228236")
    .setTitle("High-Performance Java Persistence")
    .setAuthor("Vlad Mihalcea");

    entityManager.persist(book);

    return book;
});

doInJPA(entityManager -> {
    Session session = entityManager.unwrap(Session.class);

    session.update(_book);
});

Hibernateは次のSQLステートメントを実行します。

INSERT INTO book (
    author, 
    isbn, 
    title, 
    id
) 
VALUES (
    'Vlad Mihalcea', 
    '978-9730228236', 
    'High-Performance Java Persistence', 
    1
)

SELECT 
    b.id,
    b.author AS author2_0_,
    b.isbn AS isbn3_0_,
    b.title AS title4_0_
FROM 
    book b
WHERE 
    b.id = 1

エンティティが変更されていないことをHibernateダーティチェックメカニズムが検出したため、今回は UPDATE が実行されないことに注意してください。

SaveOrUpdate

Hibernate固有の saveOrUpdate メソッドは、単に save および update のエイリアスです。

  

saveOrUpdate メソッドは、 DefaultSaveOrUpdateEventListener Hibernateイベントリスナーによって処理される SaveOrUpdateEvent をトリガーします。したがって、 update メソッドは save および saveOrUpdate メソッドと同等です。

現在、次の例に示すように、エンティティを永続化する場合、または UPDATE を強制する場合、 saveOrUpdate を使用できます。

Book _book = doInJPA(entityManager -> {
    Book book = new Book()
    .setIsbn("978-9730228236")
    .setTitle("High-Performance Java Persistence")
    .setAuthor("Vlad Mihalcea");

    Session session = entityManager.unwrap(Session.class);
    session.saveOrUpdate(book);

    return book;
});

_book.setTitle("High-Performance Java Persistence, 2nd edition");

doInJPA(entityManager -> {
    Session session = entityManager.unwrap(Session.class);
    session.saveOrUpdate(_book);
});

NonUniqueObjectException

に注意してください

save update 、および saveOrUpdate で発生する可能性のある問題の1つは、永続コンテキストに同じIDのエンティティ参照が既に含まれている場合です。および次の例と同じタイプのもの:

Book _book = doInJPA(entityManager -> {
    Book book = new Book()
    .setIsbn("978-9730228236")
    .setTitle("High-Performance Java Persistence")
    .setAuthor("Vlad Mihalcea");

    Session session = entityManager.unwrap(Session.class);
    session.saveOrUpdate(book);

    return book;
});

_book.setTitle(
    "High-Performance Java Persistence, 2nd edition"
);

try {
    doInJPA(entityManager -> {
        Book book = entityManager.find(
            Book.class, 
            _book.getId()
        );

        Session session = entityManager.unwrap(Session.class);
        session.saveOrUpdate(_book);
    });
} catch (NonUniqueObjectException e) {
    LOGGER.error(
        "The Persistence Context cannot hold " +
        "two representations of the same entity", 
        e
    );
}

今、上記のテストケースを実行すると、2番目の EntityManager には既に Book エンティティが含まれているため、Hibernateは NonUniqueObjectException をスローします。 update に渡す識別子と同じ識別子。永続コンテキストは同じエンティティの2つの表現を保持できません。

org.hibernate.NonUniqueObjectException: 
    A different object with the same identifier value was already associated with the session : [com.vladmihalcea.book.hpjp.hibernate.pc.Book#1]
    at org.hibernate.engine.internal.StatefulPersistenceContext.checkUniqueness(StatefulPersistenceContext.java:651)
    at org.hibernate.event.internal.DefaultSaveOrUpdateEventListener.performUpdate(DefaultSaveOrUpdateEventListener.java:284)
    at org.hibernate.event.internal.DefaultSaveOrUpdateEventListener.entityIsDetached(DefaultSaveOrUpdateEventListener.java:227)
    at org.hibernate.event.internal.DefaultSaveOrUpdateEventListener.performSaveOrUpdate(DefaultSaveOrUpdateEventListener.java:92)
    at org.hibernate.event.internal.DefaultSaveOrUpdateEventListener.onSaveOrUpdate(DefaultSaveOrUpdateEventListener.java:73)
    at org.hibernate.internal.SessionImpl.fireSaveOrUpdate(SessionImpl.java:682)
    at org.hibernate.internal.SessionImpl.saveOrUpdate(SessionImpl.java:674)

マージ

NonUniqueObjectException を回避するには、JPA EntityManager によって提供され、Hibernate Sessionによって継承される merge メソッドを使用する必要があります。 も同様です。

この記事で説明されているように、 merge データベースから新しいエンティティスナップショットを取得します

次の答えはどれも正しくありません。 これらの方法はすべて同じように見えますが、実際にはまったく異なることを行います。 短いコメントをするのは難しいです。これらの方法に関する完全なドキュメントへのリンクを提供する方が良い: http://docs.jboss.org/hibernate /core/3.6/reference/en-US/html/objectstate.html

上記の回答のいずれも完全ではありません。 Leo Theobaldの回答は最も近い回答に見えます。

基本的なポイントは、休止状態がエンティティの状態をどのように処理し、状態が変化したときにエンティティをどのように処理するかです。フラッシュとコミットに関してもすべて確認する必要がありますが、誰もが完全に無視しているようです。

Hibernateの保存方法は使用しないでください。休止状態でも存在することを忘れてください!

持続

誰もが説明したように、Persistは基本的にエンティティを" Transient"から移行します状態を「管理対象」に変更状態。この時点で、スラッシュまたはコミットによりinsertステートメントを作成できます。ただし、エンティティは「管理対象」のままです。状態。これはフラッシュでは変わりません。

この時点で、「持続」する場合再び変更はありません。そして、永続化されたエンティティを永続化しようとすると、それ以上の保存はありません。

実体を排除しようとすると、楽しみが始まります。

エビクトは、エンティティを「管理」から移行するHibernateの特別な機能です。 「デタッチ」に。分離されたエンティティで永続化を呼び出すことはできません。それを行うと、Hibernateは例外を発生させ、トランザクション全体がコミット時にロールバックされます。

マージと更新

これらは、異なる方法で処理されたときに異なる処理を行う2つの興味深い関数です。どちらも、エンティティを「分離」から移行しようとしています。状態を「管理対象」に変更状態。ただし、異なる方法で行います。

Detachedは一種の「オフライン」を意味するという事実を理解します。状態。管理された手段" Online"状態。

以下のコードを確認してください:

Session ses1 = sessionFactory.openSession();

    Transaction tx1 = ses1.beginTransaction();

    HibEntity entity = getHibEntity();

    ses1.persist(entity);
    ses1.evict(entity);

    ses1.merge(entity);

    ses1.delete(entity);

    tx1.commit();

これを行うとき?何が起こると思いますか? これが例外を発生させると言った場合、あなたは正しいです。これは、マージがエンティティオブジェクトに対して機能しているため、例外が発生します。エンティティオブジェクトは切り離された状態です。ただし、オブジェクトの状態は変更されません。

シーンの背後で、マージは選択クエリを発生させ、基本的に接続状態のエンティティのコピーを返します。以下のコードを確認してください:

Session ses1 = sessionFactory.openSession();

    Transaction tx1 = ses1.beginTransaction();
    HibEntity entity = getHibEntity();

    ses1.persist(entity);
    ses1.evict(entity);

    HibEntity copied = (HibEntity)ses1.merge(entity);
    ses1.delete(copied);

    tx1.commit();

上記のサンプルは、マージによって永続化された状態のコンテキストに新しいエンティティが取り込まれたため機能します。

更新では、マージのようなエンティティのコピーは実際には取得されないため、更新で適用すると同じように機能します。

Session ses1 = sessionFactory.openSession();

    Transaction tx1 = ses1.beginTransaction();

    HibEntity entity = getHibEntity();

    ses1.persist(entity);
    ses1.evict(entity);

    ses1.update(entity);

    ses1.delete(entity);

    tx1.commit();

同時にデバッグトレースでは、UpdateがマージのようなselectのSQLクエリを上げていないことがわかります。

削除

上記の例では、削除については説明せずに削除を使用しました。削除は、基本的にエンティティを管理状態から「削除済み」に移行します。状態。また、フラッシュまたはコミットされると、保存する削除コマンドが発行されます。

ただし、エンティティを「管理対象」に戻すことは可能です。 「削除」からの状態persistメソッドを使用した状態。

上記の説明により、疑問点が明確になることを期待してください。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top