영속성관리
JPA에서 데이터베이스 테이블에 맞춰 엔티티를 매핑하여 생성해보겠습니다.

이러한 형태의 테이블이 있다고 가정해보겠습니다. (연관관계가 없는 상태 Member테이블에 team_id를 그대로 가지고 있는다. )
@Entity
@Data
public class Member {
@Id @GeneratedValue
@Column(name = "MEMBER_ID")
private Long id;
@Column(name = "USERNAME")
private String name;
@Column(name = "TEAM_ID")
private String teamId;
}
@Entity
@Data
public class Team {
@Id @GeneratedValue
@Column(name = "TEAM_ID")
private Long id;
private String name;
}
이러한 형태로 된다면 아래와 같이 외래키 식별자를 직접 다루게 된다.
Team team = new Team();
team.setName("TeamA");
em.persist(team);
Member member = new Member();
member.setUsername("member1");
member.setTeamId(team.getId());
em.persist(member);
tx.commit();
만약 조회시를 하려하면 아래와 같이 한번에 조회가 되질 안호고 team의 id값을 얻어서 그 id를 통해 team 엔티티를 다시 find를 통해 조회를 해야한다.
Member findMember = em.find(Member.class, member.getId());
Long findTeamId = findMember.getTeamId();
Team findTeam = em.find(Team.class, findTeamId);
객체 참조가 되어있지 않아 연관 정보를 가져오지 못하기 때문이다.
단방향 연관관계
그럼 연관관계를 맺는 형태로 만들어보자. (Member에서 Team으로의 방향의 단방향)
그렇다면 Member엔티티에는 team_id가 아닌 Team을 객체상태로 가지고 있어야 한다.
Member엔티티에서
@Column(name = "TEAM_ID")
private String teamId;
해당 구문은 private Team team으로 변경되고
누가 다(N)이고 일인지 구별하기 위한 @ManyToOne이 추가되고
조인할 컬럼을 명시적으로 @JoinColumn(name = "TEAM_ID")를 통해 알려준다.
최종적으로는 아래와 같이 구분이 변경될 것이다.
@ManyToOne
@JoinColumn(name = "TEAM_ID")
private Team team
그렇다면 영속화 하는 작업 또한 아래와 같이 간단히 변경될 수 있다.
Team team = new Team();
team.setName("TeamA");
em.persist(team);
Member member = new Member();
member.setUsername("member1");
member.setTeam(team);
em.persist(member);
tx.commit();
team을 조회하는 구분도
Member findMember = em.find(Member.class, member.getId());
Team findTeam = findMember.getTeam();
이렇게 바로 조회가 가능해진다.
만약 Team에서도 Member에 관한 참조가 가능하게 하려면 양방향 연관관계를 맺어주면 된다.
Team엔티티에 Member를 담는 참조변수 선언 :
@OneToMany(mappedBy = "team") // 1 : N 의 관계라는 뜻, mappedBy는 member의 team 변수에 의해 연관관계 매핑이 되었다는 의미
private List<Member> members = new ArrayList(); //NPE가 발생하지 않도록 List형태로 초기화
연관관계의 주인(Owner)
양방향 매핑 규칙
* 객체의 두 관계중 하나를 연관관계의 주인으로 지정
*연관관계의 주인만이 외래 키를 관리 (등록, 수정)
*주인이 아닌쪽은 읽기만 가능
* 주인은 mappedBy 속성 사용x
(누구를 주인으로 설정해야하나? ====> 외래키가 있는 곳을 주인으로 정해라, 보통 N:1 관계일때 N쪽이 외래키를 관리하는 것이 합리적이다.)
*양방향 매핑시 가장 많이 하는 실수
연관관계의 주인에 값을 입력하지 않는다.

JPA에서는 team의 Members객체는 연견관계의 주인이 아닌 읽기 전용이라서 아무런 변화가 일어나지 않는다.
그렇기 때문에 Member테이블에서 team_id 컬럼은 null로 들어갈것이다.
Team team = new Team();
team.setName("TeamA");
em.persist(team);
Member member = new Member();
member.setName("member1");
team.getMembers().add(member);
member.setTeam(team);
em.persist(member);
이렇게 양쪽에다가 값을 입력해주는게 좋다. team의 members객체에 값을 안 넣어주면 객체로서의 값이 null일 수도 있기때문이다.
'JPA' 카테고리의 다른 글
| [JAVA]JPA_즉시로딩과 지연로딩 (0) | 2024.10.30 |
|---|---|
| [JAVA] JPA_상속관계 매핑 (0) | 2024.10.27 |
| [JAVA] JPA_연관관계 (0) | 2024.10.27 |
| [JAVA] JPA_영속성 관리 (0) | 2024.10.18 |
| [JAVA] JPA란? (0) | 2024.10.18 |