자바 ORM 표준 JPA 프로그래밍 [5-2]

김종하·2022년 7월 24일
0

JPA

목록 보기
8/10

자바 ORM 표준 JPA 프로그래밍 - 김영한
책 내용을 정리한 내용입니다.
챕터5 - 연관관계 매핑 기초
5.3 양방향 연관관계
5.4 연관관계의 주인
5.5 skip
5.6 양방향 연관관계의 주의점
5.7 skip

양방향 연관관계

양방향 연관관계 ? 관계를 맺는 객체가 서로에 대한 접근이 가능한 관계

public class Member {
    @Id
    private Long id;

    private String userName;

    @ManyToOne
    private Team team;
}

public class Team {
    @Id
    private Long id;

    private String name;

    @OneToMany(mappedBy = "team")
    private List<Member> members;
}

연관관계의 주인

@OneToMany 의 속성에는 mappedBy 속성이 있다. 해당 속성은 관계의 주인을 설정하는 속성이다.
JPA 에서는 두 객체 연관관계 중 하나를 정해서 테이블의 외래키를 관리해야하고 관리하는 쪽을 연관관계의 주인 이라고 한다.
(주인이 아닌쪽에서 mappedBy 속성을 사용해 주인을 지정한다)

  • 연관관계의 주인만이 외래키를 관리(등록, 수정, 삭제) 할 수 있다.
  • 주인이 아닌쪽은 읽기만 가능하다.
  • 연관관계의 주인은 외래키가 있는 곳으로 1:N 관계에서는 항상 N 쪽이 연관관계의 주인이다.

양방향 연관관계의 주의점

연관관계의 주인에게는 값을 입력하지 않고 주인이 아닌 곳에만 값을 입력하면
데이터베이스에 반영되지 않는다.

    @Transactional
    public void save(){
        Member member1 = new Member(1l, "member1");
        em.persist(member1);

        Member member2 = new Member(2l, "member2");
        em.persist(member2);

        Team team1 = new Team(1l, "team1");
        team1.getMembers().add(member1);
        team1.getMembers().add(member2);
        em.persist(team1);
    }

  • 연관관계의 주인에만 값을 저장하면 JPA 는 테이블에 매핑시켜준다.
    하지만 객체 상태를 고려해 양쪽 모두 값을 세팅해주는 것이 맞다.

연관관계 편의 메소드

양방향 연관관계는 결국 양쪽 다 신경 써야함으로 연관관계를 수정하는 부분은 두 쪽 모두 수정이 일어날 수 있도록 로직을 만들어 준다.

        /*
        순수한 객체 연관관계를 고려하지 않는 경우
        테이블에는 관계가 생성되지만
        객체는 모르는 상태가 된다. 
        */
        Team team1 = new Team(1l, "team1");
        em.persist(team1);

        Member member1 = new Member(1l, "member1");
        member1.setTeam(team1);
        em.persist(member1);

        Member member2 = new Member(2l, "member2");
        member2.setTeam(team1);
        em.persist(member2);

        List<Member> members = team1.getMembers();
        System.out.println("size : " + members.size()); // 0 출력
        
    
    -----------------
    
    // setTeam 양방향 관계를 모두 설정하는 연관관계 편의메소드로 변경해보자.
    public void setTeam(Team newTeam) {
        this.team = newTeam;
        newTeam.getMembers().add(this);
    } 
    
    --> System.out.println("size : " + members.size()); // 2 출력 

0개의 댓글