liguofeng29’s blog

個人勉強用ブログだっす。

Hibernate - 永続化オブジェクト

参考:第10章 オブジェクトを扱う

永続化クラスの要件

永続化オブジェクトの状態

  • 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();
    }
}