6. 다양한 연관관계 매핑 (일대다)

HotFried·2023년 9월 26일
0

일대다 단방향

  • 일대다 단방향은 일대다(1:N)에서 1(일)이 연관관계의 주인

  • 일대다 관계에서 테이블을 보면 N(다)쪽에 외래 키가 있다.

  • 객체와 테이블의 차이 때문에 반대편 테이블의 외래 키를 관리하는 특이한 구조

  • @JoinColumn을 꼭 사용해야한다. 그렇지 않으면 조인 테이블 방식을 사용한다.
    (중간에 테이블을 하나 추가)

Team 엔티티

@Entity
public class Team {

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    @Column(name = "TEAM_ID")
    private Long id;

    // 1에서 N을 참조한다.
    @OneToMany
    @JoinColumn(name = "TEAM_ID")
    private List<Member> members = new ArrayList<>();
}

JpaMain

public class JpaMain {

    public static void main(String[] args) {
        Member member = new Member();
        member.setUsername("member1");

        em.persist(member);

        Team team = new Team();
        team.setName("teamA");
        
        //
        team.getMembers().add(member);
		//
        em.persist(team);

        tx.commit();
    }
}
Hibernate:
	/* insert hellojpa.Member
    	*/ insert
        into
        	Member
            (USERNAME, MEMBER_ID)
        values
        	(?, ?)
Hibernate:
	/* insert hellojpa.Team
    	*/ insert
        into
        	Team
            (name, TEAM_ID)
        values
        	(?, ?)

commit()시점에 insert 쿼리가 나가는 것은 당연하다.
하지만 일대다 관계에서는 추가적으로 쿼리가 발생한다.

Hibernate:
	/* create one-to-many row hellojpa.Team.members */ update
    	Member
    set
    	TEAM_ID=?
    where
    	MEMBER_ID=?

DB에서 외래키는 MEMBER테이블에서 관리가 되고 있기 때문에, 추가적으로 별도의 쿼리가 나가는 것이다.


정리

  • 일대다 단방향 매핑의 단점

    • 엔티티가 관리하는 외래 키가 다른 테이블에 있음
    • 연관관계 관리를 위해 추가로 UPDATE SQL 실행

  • 일대다 단방향 매핑보다는 다대일 양방향 매핑을 사용하자


일대다 양방향

일대다 단방향의 코드 + Member 엔티티에 @JoinColumn어노테이션을 추가해줘야 한다.

@Entity
public class Member {

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Long id;
    private String name;

    @ManyToOne
    // 양방향 참조를 억지로 만들면서 읽기 전용으로 강제한다.
    @JoinColumn(name = "TEAM_ID", insertable = false, updateble = false)
    private Team team;
}
  • 둘 다 team_id를 참조하는 연관 관계의 주인이 되어버린다.
  • 어디가 기준인지 모르기 때문에 insertable과 updateble로 읽기 전용을 강제한다.

정리

  • 이런 매핑은 공식적으로 존재하지 않는다.

  • @JoinColumn(insertable=false, updatable=false)

  • 읽기 전용 필드를 사용해서 양방향 처럼 사용하는 방법

  • 다대일 양방향을 사용하자


참고 :

김영한. 『자바 ORM 표준 JPA 프로그래밍』. 에이콘, 2015.

자바 ORM 표준 JPA 프로그래밍 - 기본편

profile
꾸준하게

0개의 댓글