EclipseLinkでManyToManyのモデルを扱う


この記事の所要時間: 53

JPA実装として人気だったHibernateですが、今後はEclipseLinkが主流になるらしい。
Hibernateつぶし? – ひがやすを blog

多対多のサンプルがWeb上に見つからなかったのでメモ。

CREATE TABLE IF NOT EXISTS <code>entries</code> (
  <code>id</code> int(11) NOT NULL AUTO_INCREMENT,
  <code>subject</code> varchar(255) NOT NULL,
  <code>content</code> text NOT NULL,
  PRIMARY KEY (<code>id</code>)
) ENGINE=InnoDB  DEFAULT CHARSET=utf8 AUTO_INCREMENT=2 ;

CREATE TABLE IF NOT EXISTS <code>categories</code> (
  <code>id</code> int(11) NOT NULL AUTO_INCREMENT,
  <code>name</code> varchar(255) NOT NULL,
  <code>description</code> text NOT NULL,
  PRIMARY KEY (<code>id</code>)
) ENGINE=InnoDB  DEFAULT CHARSET=utf8 AUTO_INCREMENT=4 ;

CREATE TABLE IF NOT EXISTS <code>categories_entries</code> (
  <code>entry_id</code> int(11) NOT NULL,
  <code>category_id</code> int(11) NOT NULL,
  PRIMARY KEY (<code>entry_id</code>,<code>category_id</code>)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

こんなテーブルがあったとすると、entriesとcategoriesに対応するエンティティにそれぞれ次のフィールドを追加する。

@Entity
@Table(name = "entries")
class Entry implements Serializable {
    @ManyToMany
    @JoinTable(name="categories_entries",
        joinColumns={@JoinColumn(name="entry_id")},
        inverseJoinColumns={@JoinColumn(name="category_id")})
    private Set<Category> categories = new HashSet<Category>();
    // アクセッサメソッドも必要
}

@Entity
@Table(name = "categories")
class Category implements Serializable {
    @ManyToMany(mappedBy="categories")
    private Collection<Entry> entries = new ArrayList<Entry>();
    // アクセッサメソッドも必要
}

以下で永続化インスタンスを取得。

EntityManagerFactory emf = Persistence.createEntityManagerFactory("JavaApplication1PU");
EntityManager em = emf.createEntityManager();
Query q = em.createQuery("SELECT e FROM Entry e");
List<Entry> entries = q.getResultList();
Iterator<Entry> it = entries.iterator();
while (it.hasNext()) {
    Entry entry = it.next();
    logger.debug("id: {}", entry.getId());
    logger.debug("subject: {}", entry.getSubject());
    logger.debug("content: {}", entry.getContent());
    Set<Category> categories = entry.getCategories();
    Iterator<Category> itc = categories.iterator();
    while (itc.hasNext()) {
        Category category = itc.next();
        logger.debug("category: {}", category.getName());
    }
}
em.close();
emf.close();

原因不明の病

一応これで動いたけど、SwingGUIアプリケーションだとタイミングによってなぜかエラーが出たり出なかったりする。まったく同じようなプロジェクトを作ったら何故かそっちはエラーが全く出ない。

一筋の光

一旦生成物を削除して実行したら直った。Javaは何故かこういうことが多いので注意が必要。

蛇足

JPA 2.0を使う場合はJava6推奨らしい。

投稿者紹介

株式会社ユニキャスト
私たちは、テクノロジに魅せられた個性あふれるメンバーによって構成された茨城県日立市に本社を構えるベンチャー企業です。
”テクノロジを通して「驚き」と「感動」を創造し、人々の「夢」と「笑顔」を支えます。” の経営理念をモットーに明るい未来を描き、ワクワクする企画提案を続けて参ります。

人気の記事

コメント

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です

PAGE TOP