以前、このエントリーでJPAのリレーションについて説明しました。
今回は多対多について説明します。
テーブル構成
CDとアーティストが多対多で紐づているとします。
ER図で下記のようになっているとします。
ソース
CDのエンティティ
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 |
@Entity @Table(name = "cd") public class Cd implements Serializable { private static final long serialVersionUID = 1L; @Id @GeneratedValue(strategy = GenerationType.IDENTITY) @Basic(optional = false) @Column(name = "id") @Getter @Setter private Integer id; @Getter @Setter @Column(name = "title") private String title; @Getter @Setter @Column(name = "price") private Integer price; @Getter @Setter @Column(name = "description") private String description; @ManyToMany( mappedBy = "cdList") private List<Artist> createdByArtists; } |
Artistのエンティティ
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 |
/* * To change this license header, choose License Headers in Project Properties. * To change this template file, choose Tools | Templates * and open the template in the editor. */ package com.japrelation.entity; import java.io.Serializable; import java.util.List; import javax.persistence.Basic; import javax.persistence.Column; import javax.persistence.Entity; import javax.persistence.GeneratedValue; import javax.persistence.GenerationType; import javax.persistence.Id; import javax.persistence.JoinColumn; import javax.persistence.JoinTable; import javax.persistence.ManyToMany; import javax.persistence.Table; import lombok.Getter; import lombok.Setter; /** * * @author matsumoto */ @Entity @Table(name = "artist") public class Artist implements Serializable{ @Id @GeneratedValue(strategy = GenerationType.IDENTITY) @Basic(optional = false) @Column(name = "id") @Getter @Setter private Integer id; @Getter @Setter @Column(name = "first_name") private String firstName; @Getter @Setter @Column(name = "last_name") private String lastName; @ManyToMany @JoinTable(name="jnd_art_cd", joinColumns = @JoinColumn( name = "artist_id"), inverseJoinColumns = @JoinColumn(name="cd_id")) private List<Cd> cdList; } |
この場合Artist側が所有者になり、被所有者側のCdにはmappedByが付加されます。
両方にmappedByを書くと適切な結果が得られないようです。
データベースにアクセスするソース
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 |
/* * To change this license header, choose License Headers in Project Properties. * To change this template file, choose Tools | Templates * and open the template in the editor. */ package com.japrelation.main; import com.japrelation.entity.Artist; import com.japrelation.entity.Cd; import com.japrelation.entity.SampleOrder; import java.util.List; import javax.persistence.EntityManager; import javax.persistence.EntityManagerFactory; import javax.persistence.EntityTransaction; import javax.persistence.Persistence; public class SampleFacade { private EntityManagerFactory fac; private EntityManager em; private EntityTransaction tx; public SampleFacade(){ fac = Persistence.createEntityManagerFactory("com_japrelation_jar_1.0.0-SNAPSHOTPU"); em = fac.createEntityManager(); tx = em.getTransaction(); } public List<Cd> getCdList(){ return em.createQuery(" SELECT c FROM Cd c ",Cd.class).getResultList(); } public List<Artist> getArtistList(){ return em.createQuery(" SELECT a FROM Artist a ",Artist.class).getResultList(); } } |
Mainのソース
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
/* * To change this license header, choose License Headers in Project Properties. * To change this template file, choose Tools | Templates * and open the template in the editor. */ package com.japrelation.main; import com.japrelation.entity.Artist; import com.japrelation.entity.Cd; import com.japrelation.entity.SampleOrder; import java.util.List; public class Controller { public static void main(String[] args){ SampleFacade sf = new SampleFacade(); //多対多 List<Cd> cdList = sf.getCdList(); //多対多 List<Artist> artistList = sf.getArtistList(); } } |
参考図書
Beginning Java EE 6~GlassFish 3で始めるエンタープライズJava
http://www.amazon.co.jp/dp/4798124605
この本のP108~112を参考にしました。