Entity 연관관계 매핑 후 연관관계 주인의 값을 바꾸면 다른 객체의 값도 바뀐다.

안석우(문과대학 철학)·2023년 12월 29일
0

JPA

목록 보기
1/7

Member와 Team은 자바 객체이고 MEMBER와 TEAM은 각 자바 객체를 보고 만든 DB의 Table이다.

각 Member는 하나의 Team에 속해있고(one and only) 각 Team에는 여러 Member가 속할 수 있다.

이 때 이 연관관계의 주인은 Member인데, 주인인 Member에서 Team을 바꾸는 명령(Member.setTeam())을 했을 때 변경사항이 Team에도 잘 반영이 되는지를 확인하고자한다.(결론부터 말하면 잘 반영된다.)

아래 코드는 핵심부분만 발췌했고 Member와 Team의 연관관계는
@ManyToOne
@JoinColumn(name = "TEAM_ID")

@OneToMany(mappedBy = "team")
등의 annotation을 사용해서 잘 만들어뒀다.

tx.begin(); // transaction시작

            Team team = new Team();
            team.setName("teamA");
            em.persist(team);

            Member member = new Member();
            member.setUsername("member1");
            member.setTeam(team);
            em.persist(member);

            Member member2 = new Member();
            member2.setUsername("member2");
            em.persist(member2);
//
            em.flush();
            em.clear();

            Member findmemeber = em.find(Member.class,member.getId());
            List<Member> findmembers = findmemeber.getTeam().getMembers();
//
            findmembers.add(member2);
// 원래 member1만 findmembers에 있었는데(member2는 team을 세팅하지 않았기 때문에) member2도 넣어준다.

            for (Member findmember : findmembers) {
                System.out.println("member id:"+findmember.getTeam().getTeamId());
            }
// 출력결과 1, null

            member2.setTeam(team);
            
            em.merge(member2);
            em.flush();
            em.clear();
//      member2의 팀을 teamd으로 세팅해준다.
//      Member 클래스와 Team클래스는 N 대 1 관계로 연관관계 매핑되어있고
//      ****Member 클래스가 주인이기 때문에 위의 findmembers에 있는 
// 		member2의 teamId도 null에서 1로 바뀐다.***

//   DB의 member2의 teamId
//   도 null에서 1로 바뀐다.(member2.setTeam(team)의 변경사항이
//   DB에 반영된다.)
//  em.clear()는 영속성 컨텍스트를 비우기 때문에 member2를 다시 merge해서 영속성 컨텍스트에 등록시켜주고
// flush()를 통해서 DB에 쿼리를 날려 teamId를 null에서 1로 바꾼다.

// 위의 세줄(em 세 줄)을 주석처리하면 생각한대로 동작하지 않을 것이다.
// setTeam(team)해도 member2가 영속성 컨텍스트의 관리하에 있지 않기 때문이다.
            
            for (Member findmember : findmembers) {
                System.out.println("member id:"+findmember.getTeam().getTeamId());
            }
// 출력결과 1, 1

            em.flush();
            em.clear();


            tx.commit();

em.clear()는 영속성 컨텍스트를 비워준다.
참고: https://velog.io/@chosj1526/JPA-commit%EA%B3%BC-flush%EC%97%90-%EA%B4%80%ED%95%B4-%EC%98%81%EC%86%8D-%EC%BB%A8%ED%85%8D%EC%8A%A4%ED%8A%B8%EC%97%90%EC%84%9C-%EC%84%B8%EC%84%B8%ED%95%98%EA%B2%8C-%EC%96%B4%EB%96%A4-%EC%9D%BC%EC%9D%B4-%EC%9D%BC%EC%96%B4%EB%82%A0%EA%B9%8C-%EB%8D%B0%EC%9D%B4%ED%84%B0-%EC%82%AD%EC%A0%9C-%EB%B0%8F-%EC%88%98%EC%A0%95-%EC%8B%9C-1%EC%B0%A8-%EC%BA%90%EC%8B%9C%EC%97%90%EC%84%9C-%EB%B0%9C%EC%83%9D%ED%95%98%EB%8A%94-%ED%98%84%EC%83%81-flush%EC%9D%98-%EC%A7%84%EC%A7%9C-%EC%9D%98%EB%AF%B8

0개의 댓글