영속성관리

 

 

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

+ Recent posts