Hibernate - 永続化オブジェクト
永続化クラスの要件
- パラメータなしのコンストラクター
- ID属性
- setter,getter
- 非finalクラス
- equals(), hashCode()
永続化オブジェクトの状態
- Transient : newした状態
- Persistent : sessionスコープにある
- Detached : Persistent状態だったオブジェクトがsessionクローズされた状態
・Transient ⇒ Persistent
- Serializable save(Object obj)
- Serializable save(Object obj, Object pk)
- void persist(Object obj)
- void save(Object obj, Object pk)
import java.math.BigDecimal; import org.hibernate.Session; import org.hibernate.SessionFactory; import org.hibernate.Transaction; import org.hibernate.boot.registry.StandardServiceRegistryBuilder; import org.hibernate.cfg.Configuration; import org.hibernate.service.ServiceRegistry; import entity.Item; public class TestPersistent { public static void main(String[] args) { Configuration conf = new Configuration().configure(); ServiceRegistry serviceRegistry = new StandardServiceRegistryBuilder() .applySettings(conf.getProperties()).build(); // SessionFactory生成 SessionFactory sf = conf.buildSessionFactory(serviceRegistry); // Session生成 Session session = sf.openSession(); // Transient状態 Item item = new Item(); item.setPrice(new BigDecimal(100)); item.setName("item01"); // TX開始 Transaction tx = session.beginTransaction(); // Transient状態 ⇒ Persistent状態 session.save(item); // save(object, pk) // persist(object) TX外で実行された場合、即時insert発行はしない // persist(object, pk) // コミット tx.commit(); session.close(); } }
・Persistent取得
- load : 遅延取得、データない場合例外
- get : 即時取得、データない場合null
- ロックモード指定可能 : LockOptions.XXXX
import java.math.BigDecimal; import org.hibernate.Session; import org.hibernate.SessionFactory; import org.hibernate.boot.registry.StandardServiceRegistryBuilder; import org.hibernate.cfg.Configuration; import org.hibernate.service.ServiceRegistry; import entity.Item; public class TestPersistent2 { public static void main(String[] args) { Configuration conf = new Configuration().configure(); ServiceRegistry serviceRegistry = new StandardServiceRegistryBuilder() .applySettings(conf.getProperties()).build(); // SessionFactory生成 SessionFactory sf = conf.buildSessionFactory(serviceRegistry); // Session生成 Session session = sf.openSession(); // 即時SQL発行 Item item1 = (Item) session.get(Item.class, 15); // 遅延SQL発行 Item item2 = (Item) session.load(Item.class, 15); // 即時SQL発行 ⇒ null Item item3 = (Item) session.get(Item.class, 999); // 遅延SQL発行 Item item4 = (Item) session.load(Item.class, 999); // この時loadが実行されSQL発行 // Exception in thread "main" org.hibernate.ObjectNotFoundException: // No row with the given identifier exists: [entity.Item#999] item4.setPrice(new BigDecimal(999)); session.close(); } }
・Persistent状態オブジェクト更新
import org.hibernate.Session; import org.hibernate.SessionFactory; import org.hibernate.Transaction; import org.hibernate.boot.registry.StandardServiceRegistryBuilder; import org.hibernate.cfg.Configuration; import org.hibernate.service.ServiceRegistry; import entity.Item; public class TestPersistent2 { public static void main(String[] args) { Configuration conf = new Configuration().configure(); ServiceRegistry serviceRegistry = new StandardServiceRegistryBuilder() .applySettings(conf.getProperties()).build(); // SessionFactory生成 SessionFactory sf = conf.buildSessionFactory(serviceRegistry); // Session生成 Session session = sf.openSession(); // TX開始 Transaction tx = session.beginTransaction(); // Persistentオブジェクト取得 Item item1 = (Item) session.get(Item.class, 15); item1.setName("item99"); session.flush(); tx.commit(); session.close(); // } }
・Persistent状態オブジェクト削除 : 削除されたオブジェクトはTransient状態になる
import org.hibernate.Session; import org.hibernate.SessionFactory; import org.hibernate.Transaction; import org.hibernate.boot.registry.StandardServiceRegistryBuilder; import org.hibernate.cfg.Configuration; import org.hibernate.service.ServiceRegistry; import entity.Item; public class TestPersistent3 { public static void main(String[] args) { Configuration conf = new Configuration().configure(); ServiceRegistry serviceRegistry = new StandardServiceRegistryBuilder() .applySettings(conf.getProperties()).build(); // SessionFactory生成 SessionFactory sf = conf.buildSessionFactory(serviceRegistry); // Session生成 Session session = sf.openSession(); // TX開始 Transaction tx = session.beginTransaction(); // Persistentオブジェクト取得 Item item1 = (Item) session.get(Item.class, 15); // 削除 session.delete(item1); tx.commit(); session.close(); // } }
・Detached状態オブジェクト更新
※あるセッションで使用したインスタンスを別の新しいセッションで使おうとしない限り、 update() や saveOrUpdate() や merge() を使う必要はありません。アプリケーション全体を通じて、これらのメソッドを全く使わないこともあります。
import org.hibernate.Session; import org.hibernate.SessionFactory; import org.hibernate.Transaction; import org.hibernate.boot.registry.StandardServiceRegistryBuilder; import org.hibernate.cfg.Configuration; import org.hibernate.service.ServiceRegistry; import entity.Item; public class TestPersistent4 { public static void main(String[] args) { Configuration conf = new Configuration().configure(); ServiceRegistry serviceRegistry = new StandardServiceRegistryBuilder() .applySettings(conf.getProperties()).build(); // SessionFactory生成 SessionFactory sf = conf.buildSessionFactory(serviceRegistry); // Session生成 Session session = sf.openSession(); // Persistentオブジェクト取得 Item item1 = (Item) session.get(Item.class, 14); // item1はDetached状態になる session.close(); Session session2 = sf.openSession(); // TX開始 Transaction tx = session2.beginTransaction(); item1.setName("item14"); // Persitent状態にする session2.update(item1); // save()かupdate()か // session2.saveOrUpdate(item1); // merge() // Persistent状態にはならない // session2.merge(item1); // merge() は以下のように非常に異なります: // // 同じ識別子を持つ永続化インスタンスがその時点でセッションと関連付いているならば、引数で受け取ったオブジェクトの状態を永続化インスタンスにコピーします。 // 永続化インスタンスがその時点でセッションに関連付いていないなら、データベースからそれをロードするか、あるいは、新しい永続化インスタンスを作成します。 // 永続化インスタンスが返されます。 // 引数として与えたインスタンスはセッションと関連を持ちません。それは、分離状態のままです。 tx.commit(); session2.close(); } }