可能なオブジェクトステータスオプション

お気づきかもしれませんが、オブジェクトが Hibernate にアタッチされると、その状態はPersistentまたはManagedと呼ばれます。どうですか?永続化か管理か?

それは可能です、そしてそれは可能です。JPA 仕様によれば、オブジェクトは Persist 状態を持ち、Hibernate 仕様によれば、その状態は管理対象と呼ばれます。

Hibernate では、データベースの操作はorg.hibernate.Session型のオブジェクトを通じて実行されます。JPA によれば、このクラスは javax.persistence.EntityManager という名前にする必要があります。どちらのタイプもインターフェイスであるため、これは実際には大きな問題ではありません。

org.hibernate.Sessionインターフェースは次のように宣言されます。

interface Session extends java.lang.AutoCloseable, javax.persistence.EntityManager, HibernateEntityManager,    QueryProducer, java.io.Serializable, SharedSessionContract {

}

したがって、 Sessionインターフェイスには、 EntityManagerインターフェイスにあるすべてのメソッドが含まれています。ただし、JPA 仕様がまだ存在しなかったときの Hibernate の初期バージョンから継承した独自の仕様もあります。

この全体の状況は次のように説明されます。

セッション インターフェイスが持つすべてのメソッドと、その動作の微妙な違いを見てみましょう。

persist() メソッドの微妙な違い

オブジェクトをデータベースに保存するときは、2 つのことに注意する必要があります。

まず、オブジェクトを保存すると、最終的に SQL コマンドの INSERT または UPDATE のいずれかが実行されます。第二に、これらのアクションはオブジェクトのメソッドを呼び出した直後には発生しません。セッションただし、トランザクションが終了した後に限ります。

いくつかの簡単な状況を考えてみましょう。たとえば、Userクラスがあるとします。

@Entity
public class User {
	@Id
	@GeneratedValue
    public Integer id;

	@Columnt(name=”user_name”)
    public String name;
}

persist()メソッドを使用して、そのオブジェクトをデータベースに保存しましょう。

User user = new User();
user.setName("Kolyan");
session.persist(user);

このメソッドの目的は、新しいオブジェクトをデータベースに保存することです。そのようなオブジェクトがまだ存在しない場合は、 INSERT SQL メソッドを呼び出すことによってデータベースに追加されます。

オブジェクトがすでにデータベースに存在する場合は、何も起こりません。ただし、3 番目のケース、つまり、Detached ステータスのオブジェクトをデータベースに保存しようとする場合も考えられます。この場合、例外がスローされます。例:

User user = new User();
user.setName("Kolyan");
session.persist(user);

session.evict(user);     // detach the object from the session
session.persist(user); // a PersistenceException will be thrown here!

save() メソッドの微妙な違い

save() メソッドは、現在の Hibernate によって以前のバージョンから継承されました。これは本質的にはpersist()メソッドに非常に似ており、INSERT メソッドを使用してテーブルに新しいレコードを追加します。ただし、これにはいくつかの興味深いニュアンスがあります。

まず、このメソッドは値、つまりオブジェクトの新しい ID を返します。すでにご存知のとおり、オブジェクトには通常、データベースに追加される前には ID がなく、データベースによってすでに割り当てられています。したがって、セッション オブジェクトのsave()メソッドは、保存されたオブジェクトに割り当てられた ID を返します。

重要!Hibernate ID 仕様によれば、単なる数値ではなく、任意のシリアル化可能なオブジェクトにすることができます。文字列、数値、列挙型など、データベース内のテーブルの 1 つの列に完全に入れることができるものであれば何でも構いません。

save()メソッドにはシリアル化された結果型があるため、その結果は正しい型にキャストする必要があります。

User user = new User();
user.setName("Kolyan");
Integer id = (Integer) session.save(user);

また、オブジェクトが Detached 状態の場合、save()メソッドの動作は異なります。このようなオブジェクトは新しいものとみなされ、単純に別のエントリが追加されます。

User user = new User();
user.setName("Kolyan");
Integer id = (Integer) session.save(user);

session.evict(user); 	// detach the object from the session
Integer id2 = (Integer) session.save(user);

id 変数と id2 変数は異なります。save()操作ごとに 1 つずつ、データベース内のテーブルに 2 つのレコードが追加されます。