JPA에서 연관관계 매핑의 목표는 객체의 참조와 테이블의 외래 키를 매핑하는 것이다
연관관계 매핑은 방향과 다중성에 의해 분류된다
방향을 기준으로 단방향, 양방향으로 다중성을 기준으로 일대일, 일대다, 다대일, 다대다로 분류된다
단방향 연관관계
객체 연관관계와 테이블 연관관계의 차이점
참조를 통한 연관관계는 단방향으로 양방향 관계를 위해서는 반대쪽도 필드를 추가해 참조해야 한다
즉, 양방향 연관관계라기 보다는 서로 다른 방향의 관계 두 개라는 것이 정확한 표현이다
객체는 참조를 통해 연관관계를 탐색하는 객체 그래프 탐색을 사용한다
데이터베이스는 외래 키를 사용해 연관관계를 탐색하는 조인을 사용한다
객체 관계 매핑
@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;
}
...
)
@Entity
public class Team {
@Id
@Column(name="TEAM_ID")
private String id;
private String name;
...
}
@ManyToOne
- 다대일 관계라는 매핑 정보를 나타낸다
- 연관관계 매핑 시 다중성을 나타내는 어노테이션을 필수로 사용해야 한다
- 속성: optional, fetch, cascade, targetEntity
@JoinColumn(name="TEAM_ID")
- 외래 키를 매핑할 때 사용한다
- name 속성에 매핑할 외래 키 이름을 지정한다 (기본 값은 필드명 + _ + 참조하는 테이블의 기본 키 컬럼명이다)
- 생략 가능하다
- 속성: name, referencedColumnName, foreignKey, unique, nullable, insertable, updatable, columnDefinition, table
연관관계 사용
저장
public void testSave() {
//팀1 저장
Team team = new Team("team1", "팀1");
em.persist(team1);
//회원1 저장
Member member1 = new Member("member1", "회원1");
member1.setTeam(team1); //회원 -> 팀 참조
em.persist(member1); //저장
}
회원 엔티티는 팀 엔티티를 참조하고 저장한다
이때, JPA는 참조한 팀의 식별자를 외래 키로 사용해 적절한 등록 쿼리를 생성한다
조회
1. 객체 그래프 탐색
객체를 통해 연관된 엔티티를 조회할 수 있다
2. 객체지향 쿼리 사용 (JPQL)
특정 팀에 소속된 회원만 조회하는 경우 팀과 회원을 조인해 검색 조건을 사용하면 된다 (복잡한 조회)
private static void queryLogicJoin(EntityManager em) {
String jpql = "select m from Member m join m.team t where t.name=:teamName";
List<Member> resultList = em.createQuery(jpql, Member.class)
.setParameter("teamName", "팀1")
.getResultList();
for (Member member : resultList) {
System.out.println("[query] member.username=" +
member.getUsername);
}
}
수정
private static void updateRelation(EntityManager em) {
Team team2 = new Team("team2", "팀2");
em.persist(team2);
Member member = em.find(Member.class, "member1");
member.setTeam(team2);
}
단순히 불러온 엔티티의 값만 변경하면 트랜잭션 커밋 시 플러시가 일어나면서 변경 감지 기능이 작동하고 자동으로 데이터베이스에 반영된다
연관관계 제거
private static void deleteRelation(EntityManager em) {
Member member = em.find(Member.class, "member1");
member.setTeam(null);
}
연관관계를 null로 설정해 연관관계를 제거할 수 있다
연관된 엔티티 삭제
연관된 엔티티를 삭제하기 전에 기존에 있던 연관관계를 제거하고 삭제해야 한다
그렇지 않으면 외래 키 제약 조건으로 인해 데이터베이스에서 오류가 발생한다
-> 존재하지 않는 외래 키를 참조할 수 없기 때문이다
'스터디 > JPA' 카테고리의 다른 글
다양한 연관관계 매핑 - (1) (0) | 2025.02.10 |
---|---|
연관관계 매핑 기초 - (2) (0) | 2025.02.09 |
엔티티 매핑 - (2) (0) | 2025.02.08 |
엔티티 매핑 - (1) (0) | 2025.02.08 |
영속성 관리 - (2) (0) | 2025.02.07 |