JPA 연관관계 매핑 - 단방향매핑(@ManyToOne, @OneToMany, @OneToOne)
By on October 22, 2019
JPA 연관관계 매핑
엔티티들은 어떠한 키를 기준으로 여러 엔티티와 연관 관계를 가지고 있다. JPA 의 객체 관계 매핑은 이해 하지 못하면 매우 어렵다.
JPA 에서의 연관관계는 크게 아래와 같다.
1) 방향성(Direction)
- 단방향 : 회원정보 -> 강사 또는 강사 -> 회원정보 중 한 쪽만 참조되는 경우
- 양방향 : 회원정보 -> 강사, 강사 -> 회원정보 으로 양쪽으로 참조되는 경우
2) 다중성(Multiplicity)
- 다대일(N:1)
- 일대다(1:N)
- 일대일(1:1)
- 다대다(N:M)
3) 연관관계의 주인(Owner)
- 객체를 양방향 연관관계로 만들면 연관관계의 주인을 정해야 함.
방향성(Direction)
JPA 객체 관계 매핑은 방향성을 가지고 있다. 이 방향성은 엔티티의 관계에 따라서 달라진다.
@ManyToOne(N:1) 매핑 예제를 통해서 JPA의 방향성 중 단방향에 대해서 알아보자.
- 회원 엔티티의 속성은 아래와 같다.
- 회원은 한명의 강사에 속할 수 있다.
- 회원과 강사는 다대일(N:1) 관계이다.
- 테이블 스크립트
CREATE TABLE MEMBER(
ID VARCHAR(255) NOT NULL, --아이디(기본 키)
NAME VARCHAR(255), --이름
AGE INTEGER NOT NULL, --나이
ADDRESS VARCHAR(255), --주소
TEACHER_ID VARCHAR(255), --강사ID
PRIMARY KEY (ID)
)
CREATE TABLE TEACHER (
TEACHER_ID VARCHAR(255) NOT NULL, --강사ID(기본 키)
NAME VARCHAR(255), --이름
PRIMARY KEY (TEACHER_ID)
)
1) 관계매핑 및 회원 등록
-
단방향 Annotation 정보
- @ManyToOne : 다대일(N:1) 매핑
- @OneToMany : 일대다(1:N) 매핑
- @OneToOne : 일대일(1:1) 매핑
- @JoinColumn(생략가능) : 조인 컬럼은 외래 키를 맵핑 할때 사용 됨.
-
Member Entity
@Entity @Table(name = "MEMBER") public class Member { @Id private String id; private String name; private int age; private String address; @ManyToOne @JoinColumn(name = "TEACHER_ID") private Teacher teacher; public Member(String id, String name, String address) { super(); this.id = id; this.name = name; this.address = address; } public void setTeacher(Teacher teacher) { this.teacher = teacher; } }
-
Teacher Entity
@Entity public class Teacher { @Id @Column(name = "TEACHER_ID") private String id; private String name; public Teacher(String id, String name) { this.id = id; this.name = name; } }
-
Main Class
public class Main { public static void main( String[] args ) { //엔티티 매니저 팩토리 생성 EntityManagerFactory emf = Persistence.createEntityManagerFactory("jpaExam"); //엔티티 매니저 생성 EntityManager em = emf.createEntityManager(); //엔티티 트렌젝션 생성 EntityTransaction tx = em.getTransaction(); try { //트랜잭션 시작 tx.begin(); //강사 생성 Teacher teacher1 = new Teacher("1", "이일타"); Teacher teacher2 = new Teacher("2", "김이타"); //등록 em.persist(teacher1); em.persist(teacher2); //맴버 생성 Member member1 = new Member("1", "김철수", 23, "서울특별시"); member1.setTeacher(teacher1); em.persist(member1); Member member2 = new Member("2", "이영희", 21,"부산광역시"); member2.setTeacher(teacher1); em.persist(member2); Member member3 = new Member("3", "박수지", 22, "광주광역시"); member3.setTeacher(teacher2); em.persist(member3); tx.commit();//트랜잭션 커밋 } catch (Exception e) { e.printStackTrace(); tx.rollback(); //트랜잭션 롤백 } finally { em.close(); //엔티티 매니저 종료 } emf.close(); //엔티티 매니저 팩토리 종료 } }
-
회원 등록 수행 결과
-
회원 엔티티는 강사 엔티티에 @ManyToOne 을 사용하여 다대일(N:1) 매핑이 되어있고 이때 @JoinColumn(name = “TEACHER_ID”) 외래키 설정을 통해 “TEACHER_ID” 로 연관 관계가 맺어 졌다.
-
회원 데이터
-
강사 데이터
-
2) 조회
//조회
Member findMember1 = em.find(Member.class, "1");
System.out.println("member1 : " + findMember1);
3) 수정
- memeber1 의 강사를 teacher1 에서 teacher2로 수정 해보자.
//조회
Member findMember1 = em.find(Member.class, "1");
System.out.println("member1 : " + findMember1);
//수정
findMember1.setTeacher(teacher2);
System.out.println("member1 : " + findMember1);
4) 연관관계 제거
//연관관계 제거
findMember1.setTeacher(null);
5) 회원 삭제
- 회원 정보를 삭제 하기 위해서는 기존의 연관 관계를 먼저 제거하고 삭제 해야 한다. 그렇지 않으면 외래키 오류로 DB Exception 이 발생 되게 된다.
//연관관계 제거
findMember1.setTeacher(null);
//삭제
em.remove(findMember1);
마무리
이번 포스팅에서는 @ManyToOne 예제를 통해서 JPA 의 방향성 중 단방향 매핑에 대해서 알아보았다. 다음 포스팅에서는 양방향 매핑에 대해서 정리해보자.