'extra column'에 해당되는 글 1건

  1. 2015.12.23 :: jpa ManyToMany에 Column 추가하기
개발관련/Spring 2015. 12. 23. 13:29

hibernate나 jpa나 구동 방식은 매우 흡사하나. jpa는 repository를 제공한다. 기본적으로 두개다 m:n의 경우 manytomany라는 어노테이션을 사용 하지만 가끔 m:n의 테이블에 추가 컬럼을 쓸경우가 생긴다. 


이때는 manytomany라는 어노테이션을 사용하지 않고 oneToMany를 사용하여 m:n 테이블에 컬럼을 추가한다. 그럼 예제를 보자. 

먼저 예제는 project라는 테이블과 person 테이블이 있고 이들을 project_groups라는 테이블로 OneToMany로 맵핑하는 구조이다. 

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
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
package com.zest.jpa.manytomanyextracolumn;
 
 
import java.util.List;
 
import javax.persistence.CascadeType;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.OneToMany;
 
@Entity(name="person")
public class Person {
 
    private int idx;
 
    private String name;
    private String email;
    private String password;
    
    private List<Group> groups;
    
    public Person() {
        // TODO Auto-generated constructor stub
    }
    
    public Person(String name, String email, String password) {
        // TODO Auto-generated constructor stub
        this.name = name;
        this.email = email;
        this.password = password;
    }
 
    public Person(String name, String email, String password, List<Group> groups) {
        // TODO Auto-generated constructor stub
        this.name = name;
        this.email = email;
        this.password = password;
        this.groups = groups;
    }
    
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    public int getIdx() {
        return idx;
    }
 
    public void setIdx(int idx) {
        this.idx = idx;
    }
 
    public String getName() {
        return name;
    }
 
    public void setName(String name) {
        this.name = name;
    }
 
    public String getEmail() {
        return email;
    }
 
    public void setEmail(String email) {
        this.email = email;
    }
 
    public String getPassword() {
        return password;
    }
 
    public void setPassword(String password) {
        this.password = password;
    }
    
    @OneToMany(mappedBy = "person", cascade = CascadeType.ALL)
    public List<Group> getGroups() {
        return groups;
    }
 
    public void setGroups(List<Group> groups) {
        this.groups = groups;
    }
    
 
    @Override
    public String toString() {
        // TODO Auto-generated method stub
        return "name=" + name + ", password=" + password + ", email=" + email;
    }
 
    
}
 
cs


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
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
 
package com.zest.jpa.manytomanyextracolumn;
 
 
import java.util.ArrayList;
import java.util.List;
 
import javax.persistence.CascadeType;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.OneToMany;
 
@Entity(name="project")
public class Project {
    
    private int idx;
    
    
    private String name;
    private String description;
    
    private List<Group> groups;
    
    
 
    public Project() {
        // TODO Auto-generated constructor stub
    }
    
    public Project(String name, String description){
        this.name = name;
        this.description = description;
        this.groups = new ArrayList<Group>();
        
    }
    
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    public int getIdx() {
        return idx;
    }
    public void setIdx(int idx) {
        this.idx = idx;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public String getDescription() {
        return description;
    }
    public void setDescription(String description) {
        this.description = description;
    }
    
    @OneToMany(mappedBy = "project", cascade = CascadeType.ALL, fetch=FetchType.LAZY)
    public List<Group> getGroups() {
        return groups;
    }
 
    public void setGroups(List<Group> groups) {
        this.groups = groups;
    }
    
    
    @Override
    public String toString() {
        // TODO Auto-generated method stub
        return "name=" + name + ", desc=" + description;
    }
}
 
cs


각 클래스는 @OnetoMany라는 어노티에션이 groups() 메소드에 묶여 있다. 그럼 이들을 묶어주는 groups 클래스를 보자. 


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
55
56
57
58
59
60
61
62
 
package com.zest.jpa.manytomanyextracolumn;
 
import java.io.Serializable;
 
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
 
 
@Entity(name="project_groups")
public class Group implements Serializable {
 
    private String role;
 
    private Person person;
    private Project project;
    
    public Group() {
        // TODO Auto-generated constructor stub
    }
    
    public Group(Person person, Project project, String role) {
        this.person = person;
        this.project = project;
        this.role = role;
    }
    
    @Column(name = "role")
    public String getRole() {
        return role;
    }
 
    public void setRole(String role) {
        this.role = role;
    }
 
    @Id
    @ManyToOne
    @JoinColumn(name="person_id")
    public Person getPerson() {
        return person;
    }
 
    public void setPerson(Person person) {
        this.person = person;
    }
 
    @Id
    @ManyToOne
    @JoinColumn(name="project_id")
    public Project getProject() {
        return project;
    }
 
    public void setProject(Project project) {
        this.project = project;
    }
}
 
cs


각 테이블과 맵핑되는 객체에 @ManyToOne이 존재하며 @JoinColumn으로 fk를 걸어주었다. 그리고 extra column으로 role이 존재 한다. 


마지막 테스크 코드를 보자 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
 
    @Test
    public void projectMakeEx(){
        Person person = new Person("gno2222222""gnogun@naver.com""gno");
        Project project = new Project("project122222""description");
        
        Group group = new Group(person, project, "owner");
        
        
        project.getGroups().add(group);
        
        personRepository.save(person);
        
        projectRepository.save(project);
        
        
    }
cs


각 person과 project의 repository를 사용하여 save를 하고 group은 project에 add 리스트를 해주었다. 구조가 project가 추가 되면 group도 추가 되는 구조이기때문에 위 처럼 선언한것이다. 물론 반대인 경우 person이 추가될때 그럼을 add 해도 추가 된다. 


소스는 https://github.com/zest133/hibernateTest.git 에 있으며 기존 hibernate 소스는 이 예제때문에 hibernate 버전이 변경 됨에 따라 소스 부분이 변경된 곳이 있을것이다. 


posted by 제스트
: