본문 바로가기

스터디/JPA

다양한 연관관계 매핑 - (1)

728x90
반응형

다대일


 

다대일 관계의 반대 방향은 일대다이고 일대다 관계의 반대 방향은 다대일이다

외래 키는 항상 다쪽에 있고, 연관관계의 주인은 항상 다쪽이다

다대일 양방향 [N:1, 1:N]

@Entity
public class Member (

	@Id
	@Column(name="MEMBER_ID")
	private String id;
	
	private String username;
	
	//연관관계 매핑
	@ManyToOne
	@JoinColumn(name="TEAM_ID")
	private Team team;
	
	public void setTeam(Team team) {
		this.team = team;
		
		//무한루프에 빠지지 않도록 검사
		if (!team.getMembers().contains(this)) {
			team.getMembers().add(this);
		}
	}
	...
)
@Entity
public class Team {
	
	@Id
	@Column(name="TEAM_ID")
	private String id;
	
	private String name;
	
	@OneToMany(mappedBy="team")
	private List<Member> members = new ArrayList<Member>();
	
	public void addMember(Member member) {
		this.members.add(member);
		if (member.getTeam() != this) { //무한루프에 빠지지 않도록 검사
			member.setTeam(this);
		}
	}
	...
}

연관관계 편의 메서드는 한 곳에만 작성하거나 양쪽 다 작성할 수 있는데 양쪽 모두 작성할 경우 무한루프에 빠지므로 주의해야 한다 (연관관계 편의 메서드가 서로를 호출하기 때문)

 

일대다


 

다대일 관계의 반대 방향이다

엔티티를 하나 이상 참조할 수 있으므로 Collection, List, Set, Map 중 하나를 사용해야 한다

일대다 단방향 [1:N]

반대쪽 테이블에 있는 외래 키를 관리한다

 

@Entity
public class Team {
	
	@Id @GeneratedValue
	@Column(name="TEAM_ID")
	private String id;
	
	private String name;
	
	@OneToMany
	@JoinColumn(name = "TEAM_ID") //MEMBER 테이블의 TEAM_ID
	private List<Member> members = new ArrayList<Member>();
	...
}

일대다 단방향 관계를 매핑할 때에는 @JoinColumn을 명시해야 한다

그렇지 않으면 JPA는 조인 테이블 전략을 기본으로 사용해 매핑한다

  - 조인 테이블 전략은 별도의 테이블을 만들어 연관관계를 매핑한다

 

 

일대다 단방향 매핑의 단점

 

매핑한 객체가 관리하는 외래 키가 다른 테이블에 있다는 점이 단점이다

  - 외래 키는 Member 테이블에 존재하는데 이를 관리하는 객체는 Team 객체이다

 

성능적인 문제점이 있다

  - Member 엔티티는 Team 엔티티를 모르고, 연관관계에 대한 정보는 Team 엔티티의 members가 관리한다

  - Member 엔티티를 저장할 때 MEMBER 테이블의 TEAM_ID 외래 키에 아무 값도 저장되지 않는다

  - Team 엔티티를 저장할 때 Team.members 값을 참조해 MEMBER 테이블의 TEAM_ID 외래 키를 업데이트하게 된다

  - INSERT 한번으로 끝낼 수 있는 것을 INSERT + UPDATE 두 번을 실행해야 한다

 

 

성능적인 문제 뿐만 아니라 관리적인 측면에서도 일대다 단방향 매핑은 부담스럽다

일대다 단방향 매핑 대신 다대일 양방향 매핑을 사용하는 것이 좋다

일대다 양방향 [1:N, N:1]

@ManyToOne에는 mappedBy 속성이 없기 때문에 양방향 매핑에서 @OneToMany는 연관관계의 주인이 될 수 없다

 

일대다 단방향 매핑 반대편에 같은 외래 키를 사용하는 다대일 단방향 매핑을 읽기 전용으로 추가하면 일대다 양방향 매핑을 구현할 수는 있다

@Entity
public class Team {
	
	@Id @GeneratedValue
	@Column(name="TEAM_ID")
	private String id;
	
	private String name;
	
	@OneToMany
	@JoinColumn(name = "TEAM_ID") //MEMBER 테이블의 TEAM_ID
	private List<Member> members = new ArrayList<Member>();
	...
}
@Entity
public class Member (

	@Id
	@Column(name="MEMBER_ID")
	private String id;
	
	private String username;
	
	//연관관계 매핑
	@ManyToOne
	@JoinColumn(name="TEAM_ID", insertable=false, updatable=false)
	private Team team;
	...
)

일대다 단방향 매핑의 단점을 그대로 가지고 있으므로 다대일 양방향 매핑을 사용하는 것을 추천한다

728x90
반응형

'스터디 > JPA' 카테고리의 다른 글

다양한 연관관계 매핑 - (3)  (0) 2025.02.11
다양한 연관관계 매핑 - (2)  (0) 2025.02.10
연관관계 매핑 기초 - (2)  (0) 2025.02.09
연관관계 매핑 기초 - (1)  (0) 2025.02.09
엔티티 매핑 - (2)  (0) 2025.02.08