Hibernate 入門記 コレクションその9 bag で many-to-many

今回はバッグ,要素の重複が許されるコレクションです.
そのバッグなんですが,Java のコレクションフレームワークでは標準で用意されていません.そこで,バッグを保持するプロパティの型には java.util.Collection または java.util.List を使います.
そしてそのマッピングの定義に使うのが

  • <bag> 要素

です.
例によって使い方は <set> 要素とほとんど同じ.
属性については,<set> 要素の sort が使えないだけです.
内容は全く同じで,<key> 要素で外部キーを指定して,<element> 要素・<composite-element> 要素・<one-to-many> 要素・<many-to-many> 要素・<many-to-any> 要素のいずれかでバッグの要素を記述します.
以上.(^^;


早速お試しコーナー.
重複かぁ.早耳トレンドNo1ですかねぇ.あさ美ちゃん重複しまくりだし.(^^;
ということでまずはテーブル.

CREATE TABLE HAYAMIMI (
    ID INTEGER IDENTITY,
    WEEK VARCHAR
)

CREATE TABLE MODEL (
    ID INTEGER IDENTITY,
    NAME VARCHAR
)

CREATE TABLE APPEARANCE (
    ID INTEGER IDENTITY,
    WEEK INTEGER,
    MODEL INTEGER
)

そして早耳の永続クラス.今度は週単位.

package study;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Collection;
import net.sf.hibernate.CallbackException;
import net.sf.hibernate.Lifecycle;
import net.sf.hibernate.Session;

public class Hayamimi implements Lifecycle {
    int id = -1;
    String week;
    Collection model;

    public Hayamimi() {
    }
    public Hayamimi(String week) {
        this.week = week;
        this.model = new ArrayList();
    }

    public String toString() {
        return "早耳トレンドNo1 " + week + " " + model;
    }

    public void onLoad(Session s, Serializable id) {
        System.out.println("onLoad() : " + toString());
    }
    public boolean onSave(Session s) throws CallbackException {
        System.out.println("onSave() : " + toString());
        return false;
    }
    public boolean onUpdate(Session s) throws CallbackException {
        System.out.println("onUpdate() : " + toString());
        return false;
    }
    public boolean onDelete(Session s) throws CallbackException {
        System.out.println("onDelete() : " + toString());
        return false;
    }
}

早耳のマッピングファイル.

<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
    "-//Hibernate/Hibernate Mapping DTD 2.0//EN"
    "http://hibernate.sourceforge.net/hibernate-mapping-2.0.dtd"
>
<hibernate-mapping auto-import="false" package="study">
    <class name="Hayamimi">
        <id name="id" access="field" unsaved-value="-1">
            <generator class="identity"/>
        </id>

        <property name="week" access="field"/>
        <bag name="model" access="field" table="appearance">
            <key column="week"/>
            <many-to-many column="model" class="Model"/>
        </bag>
    </class>
</hibernate-mapping>

次にモデルの永続クラス.

package study;
import java.io.Serializable;
import net.sf.hibernate.CallbackException;
import net.sf.hibernate.Lifecycle;
import net.sf.hibernate.Session;

public class Model implements Lifecycle {
    int id = -1;
    String name;

    public Model() {
    }
    public Model(String name) {
        this.name = name;
    }

    public String toString() {
        return name;
    }

    public void onLoad(Session s, Serializable id) {
        System.out.println("onLoad() : " + toString());
    }
    public boolean onSave(Session s) throws CallbackException {
        System.out.println("onSave() : " + toString());
        return false;
    }
    public boolean onUpdate(Session s) throws CallbackException {
        System.out.println("onUpdate() : " + toString());
        return false;
    }
    public boolean onDelete(Session s) throws CallbackException {
        System.out.println("onDelete() : " + toString());
        return false;
    }
}

モデルのマッピングファイル.

<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
    "-//Hibernate/Hibernate Mapping DTD 2.0//EN"
    "http://hibernate.sourceforge.net/hibernate-mapping-2.0.dtd"
>
<hibernate-mapping auto-import="false" package="study">
    <class name="Model">
        <id name="id" access="field" unsaved-value="-1">
            <generator class="identity"/>
        </id>

        <property name="name" access="field"/>
    </class>
</hibernate-mapping>

早耳とモデルのマッピングファイルを hibernate.cfg.xml に記述します.
そして実行用のクラス.

package study;
import java.util.Iterator;
import net.sf.hibernate.Session;
import net.sf.hibernate.SessionFactory;
import net.sf.hibernate.cfg.Configuration;

public class Main {
    public static void main(String[] args) {
        try {
            Configuration config = new Configuration();
            SessionFactory factory = config.configure().buildSessionFactory();

            Session session = factory.openSession();

            Model asami = new Model("あさ美");
            session.save(asami);
            Model anne = new Model("杏");
            session.save(anne);
            Model kana = new Model("香奈");
            session.save(kana);
            Model sayo = new Model("紗世");
            session.save(sayo);
            Model jun = new Model("潤");
            session.save(jun);
            Model rosa = new Model("ローサ");
            session.save(rosa);

            Hayamimi lastWeek = new Hayamimi("last week");
            lastWeek.model.add(asami);
            lastWeek.model.add(asami);
            lastWeek.model.add(kana);
            lastWeek.model.add(sayo);
            lastWeek.model.add(asami);
            session.save(lastWeek);

            Hayamimi thisWeek = new Hayamimi("this week");
            thisWeek.model.add(rosa);
            thisWeek.model.add(jun);
            thisWeek.model.add(anne);
            thisWeek.model.add(kana);
            session.save(thisWeek);

            session.flush();

            session = factory.openSession();
            Iterator it = session.find("from study.Hayamimi").iterator();
            while (it.hasNext()) {
                System.out.println(it.next());
            }
        }
        catch (Throwable e) {
            e.printStackTrace();
        }
    }
}

これを実行!!

 onSave() : あさ美
 Hibernate: insert into Model (name, id) values (?, null)
 Hibernate: CALL IDENTITY()
 onSave() : 杏
 Hibernate: insert into Model (name, id) values (?, null)
 Hibernate: CALL IDENTITY()
 onSave() : 香奈
 Hibernate: insert into Model (name, id) values (?, null)
 Hibernate: CALL IDENTITY()
 onSave() : 紗世
 Hibernate: insert into Model (name, id) values (?, null)
 Hibernate: CALL IDENTITY()
 onSave() : 潤
 Hibernate: insert into Model (name, id) values (?, null)
 Hibernate: CALL IDENTITY()
 onSave() : ローサ
 Hibernate: insert into Model (name, id) values (?, null)
 Hibernate: CALL IDENTITY()
 onSave() : 早耳トレンドNo1 last week [あさ美, あさ美, 香奈, 紗世, あさ美]
 Hibernate: insert into Hayamimi (week, id) values (?, null)
 Hibernate: CALL IDENTITY()
 onSave() : 早耳トレンドNo1 this week [ローサ, 潤, 杏, 香奈]
 Hibernate: insert into Hayamimi (week, id) values (?, null)
 Hibernate: CALL IDENTITY()
 Hibernate: insert into appearance (week, model) values (?, ?)
 Hibernate: select hayamimi0_.id as id, hayamimi0_.week as week from Hayamimi hayamimi0_
 Hibernate: select model0_.model as model__, model0_.week as week__ from appearance model0_ where model0_.week=?
 Hibernate: select model0_.id as id0_, model0_.name as name0_ from Model model0_ where model0_.id=?
 onLoad() : あさ美
 Hibernate: select model0_.id as id0_, model0_.name as name0_ from Model model0_ where model0_.id=?
 onLoad() : 香奈
 Hibernate: select model0_.id as id0_, model0_.name as name0_ from Model model0_ where model0_.id=?
 onLoad() : 紗世
 onLoad() : 早耳トレンドNo1 last week [あさ美, あさ美, 香奈, 紗世, あさ美]
 Hibernate: select model0_.model as model__, model0_.week as week__ from appearance model0_ where model0_.week=?
 Hibernate: select model0_.id as id0_, model0_.name as name0_ from Model model0_ where model0_.id=?
 onLoad() : ローサ
 Hibernate: select model0_.id as id0_, model0_.name as name0_ from Model model0_ where model0_.id=?
 onLoad() : 潤
 Hibernate: select model0_.id as id0_, model0_.name as name0_ from Model model0_ where model0_.id=?
 onLoad() : 杏
 onLoad() : 早耳トレンドNo1 this week [ローサ, 潤, 杏, 香奈]
 早耳トレンドNo1 last week [あさ美, あさ美, 香奈, 紗世, あさ美]
 早耳トレンドNo1 this week [ローサ, 潤, 杏, 香奈]

何事もなく終了.
長いこと吐血していないなぁ.何か違うことしなきゃなぁ.
まぁ,このシリーズもあとは <id-bag> で終わりのはずなので,もうちょっとの辛抱です.
がんばろ.