final Team team1 = new Team(); team1.setTeamName("team1"); team1.setTeamType(TeamType.A); entityManager.persist(team1);
final Member member1 = new Member(); member1.setUsername("member1"); member1.setAge(20); member1.setTeam(team1); // Member와 Team 간 연관관계 저장 entityManager.persist(member1);
final Member member2 = new Member(); member2.setUsername("member2"); member2.setAge(10); member2.setTeam(team1); // Member와 Team 간 연관관계 저장 entityManager.persist(member2);
양방향 연관관계 저장
양방향 연관관계 저장 시 주의할 점으로는 연관관계의 주인이 아닌 엔티티에서 연관관계를 저장해도 실제로 데이터베이스에 저장되지 않는다는 점이다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
final Member member1 = new Member(); member1.setUsername("member1"); member1.setAge(20); // member1.setTeam(team1); entityManager.persist(member1);
final Member member2 = new Member(); member2.setUsername("member2"); member2.setAge(10); // member2.setTeam(team1); entityManager.persist(member2);
final Team team1 = new Team(); team1.setTeamName("team1"); team1.setTeamType(TeamType.A); // 연관관계의 주인이 아닌 쪽에서 아래와 같이 연관관계를 저장해도 데이터베이스에는 저장되지 않는다. team1.setMembers(Lists.newArrayList(member1, member2)); entityManager.persist(team1);
그렇다고 연관관계의 주인 쪽에만 객체를 저장하지는 말고, 양쪽 방향 모두 객체를 저장해주는 것이 가장 안전하다.
아래와 같이 연관관계 저장 시 연관관계의 주인이 아닌 쪽에도 관계가 설정되도록 기능을 확장할 수 있다. 아래 예제 코드를 참조할 것.
publicvoidsetTeam(Team team){ if (this.team != null) { // 기존에 설정된 연관관계는 아래와 같이 제거해야 한다. this.team.getMembers().remove(this); } this.team = team; // 연관관계의 주인이 아닌 쪽에도 아래와 같이 관계를 설정해주는 편이 안전하다. team.getMembers().add(this); } // ... }
연관관계 조회
객체 그래프 탐색
객체 연관관계를 사용한 객체 그래프 탐색으로 연관관계 엔티티를 조회할 수 있다.
1 2
final Member member = entityManager.find(Member.class, member1.getId()); final Team team = member.getTeam();
JPQL 사용
객체지향 쿼리인 JPQL의 조인을 사용하여 연관관계 엔티티를 조회할 수 있다.
1 2 3 4 5 6 7
final String jpql = "select m from Member m join m.team t where t.teamName=:teamName"; final List<Member> resultList = entityManager.createQuery(jpql, Member.class) .setParameter("teamName", team1.getTeamName()) .getResultList(); for (final Member member : resultList) { System.out.println("member's username=" + member.getUsername()); }
연관관계 수정
엔티티의 연관관계 엔티티만 변경해두면 트랜잭션 커밋 시 변경 감지 기능이 작동하여 연관관계가 수정된다.
1 2 3 4 5 6 7 8 9
final Team team2 = new Team(); team2.setTeamName("team2"); team2.setTeamType(TeamType.B); entityManager.persist(team2);
findMember1.setTeam(team2);
final Member findMember2 = entityManager.find(Member.class, member.getId()); System.out.println(findMember2.getTeam().getTeamName());
연관관계 제거
연관관계를 null로 설정하면 연관관계가 제거된다.
1 2
final Member findMember = entityManager.find(Member.class, member.getId()); findMember.setTeam(null);
연관된 엔티티를 삭제할 때에는 기존의 연관관계 먼저 제거하고 삭제할 것. 아래 코드는 외래 키 제약조건으로 인해 오류가 발생한다.
1 2 3 4 5 6 7
member1.setTeam(team1); member2.setTeam(team2);
member1.setTeam(null); // member2.setTeam(null);
entityManager.remove(team1);
위 내용은 김영한님의 자바 ORM 표준 JPA 프로그래밍를 읽으며 개인적으로 요약 및 정리하는 내용이다. 자세한 내용이 알고 싶으면 김영한님의 자바 ORM 표준 JPA 프로그래밍을 직접 읽어보길 추천한다.