개발과정에서 회원의 입금출금 거래내역을 조회하는 과정을 개발하면서 일대다 다대일 매핑내용이 헷갈려서 복습겸 다시 내용을 정리했다.

 

하나의 회원은 거래내역들을 참조할 수 있는데 이런 관계가 일대다 관계이다.

일대다 단방향

일대다 관계에서 외래 키는 항상 다쪽 테이블에 있다.

여기서 내가 짠 코드의 Member가 TEAM의 역할이고, 거래내역 BankTransactions가 MEMBER의 역할이다.

다 쪽인 BT엔티티에는 외래 키를 매핑할 수 있는 참조 필드가 없게되고 반대쪽인 MEMBER엔티티에만 참조 필드인 BankTransactions가 있다. 따라서 반대편 테이블의 외래 키를 관리하는 특이한 모습으로 나타난다.

 

 일대다 단방향 매핑의 단점은 매핑한 객체가 관리하는 외래 키가 다른테이블에 있다는 점이다. 본인 테이블에 외래 키가 있으면 INSERT SQL한 번으로 끝낼 수 있지만, 다른 테이블에 외래 키가 있으면 연관관계 처리를 위한 UPDATE SQL을 추가로 실행해야 한다. 

 BANKTRANSACTION엔티티는 MEMBER엔티티를 모른다. 그리고 연관관계에 대한 정보는 MEMBER엔티티의 Transactions가 관리한다. 따라서 Transaction엔티티를 저장할때는 Transaction테이블의 외래 키에 아무 값도 저장되지 않는다. INSERT가 진행된후 참조 값을 확인해서 UPDATE를 해야  Transaction테이블에 있는 외래키가 업데이트되는 방식이다. 

 

결론: 일대다 단방햔 매핑을 사용하면 엔티티를 매핑한 테이블이 아닌 다른 테이블의 외래 키를 관리해야 한다.

 성능문제+관리문제가 발생한다. 좋은방법은 다대일 양방향 매핑을 사용하는 것이다. 

 

다대일 양방향

위 이미지처럼 다대일 양방향 매핑은 관리해야 하는 외래 키가 본인 테이블에 있다.

따라서 일대다 단방향 매핑 같은 문제가 발생하지 않는다. 두 매핑의 테이블 모양은 완전히 같으므로 엔티티만 수정하면된다. 

 

1
2
3
4
5
6
7
     @OneToMany(mappedBy="member")
    private List<BankTransaction> bankTransactions=new ArrayList<>();
 
     @ManyToOne(fetch=FetchType.LAZY)
    @JoinColumn(name="member_id")
    private Member member;
 
cs

양방향 설정 코드.

+ Recent posts