2010年1月3日日曜日

Hibernate の annotation

Hibernate の Annotation を試しているときに @OneToMany でつまったのでメモ。

【やりたいこと】
Projectクラスと、Memberクラスを用意して、
Project の中に Member を ArrayList で沢山保持したい。

で、作った Project.java を下に載せる。

[model.Project.java]
package model;

import java.util.ArrayList;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.OneToMany;
import javax.persistence.Table;

@Entity
@Table
public class Project {
@Id
@GeneratedValue(strategy=GenerationType.AUTO)
private Integer id;

@Column
private String name;

@OneToMany
private ArrayList members = new ArrayList();

private Project() {}
public Project(String name){
this.name = name;
}

public String getName() {
return name;
}

public void setName(String name) {
this.name = name;
}

public ArrayList getMembers() {
return members;
}

public void addMember(Member member) {
this.members.add(member);
}

}

【問題】

@OneToMany
private ArrayList members = new ArrayList();

というフィールドを作ったら以下のように怒られた。

        Exception in thread "main" java.lang.ExceptionInInitializerError
        at TestMain.HibernateUtil.(HibernateUtil.java:14)
        at TestMain.AddMember.main(AddMember.java:11)
        Caused by: org.hibernate.AnnotationException: Illegal attempt to map a non collection as a @OneToMany, @ManyToMany or @CollectionOfElements: model.Project.members
        at org.hibernate.cfg.annotations.CollectionBinder.getCollectionBinder(CollectionBinder.java:266)
        at org.hibernate.cfg.AnnotationBinder.processElementAnnotations(AnnotationBinder.java:1448)
        at org.hibernate.cfg.AnnotationBinder.bindClass(AnnotationBinder.java:754)
        at org.hibernate.cfg.AnnotationConfiguration.processArtifactsOfType(AnnotationConfiguration.java:546)
        at org.hibernate.cfg.AnnotationConfiguration.secondPassCompile(AnnotationConfiguration.java:291)
        at org.hibernate.cfg.Configuration.buildSessionFactory(Configuration.java:1333)
        at org.hibernate.cfg.AnnotationConfiguration.buildSessionFactory(AnnotationConfiguration.java:867)
        at TestMain.HibernateUtil.(HibernateUtil.java:12)
        ... 1 more

【解決方】
原因は、フィールドの型は List でないといけないらしい。 Hibernate Annotations Reference Guideより Collection、List(インデックス化 リストではなく、順序化リスト)、Map、及び Set を マップすることができます。 とのこと。

と、いうことで、

@OneToMany
private List members = new ArrayList();

にしたら、ちゃんと保存できました。 よかったよかった。