JPA에서 엔티티를 저장할 때 연관된 모든 엔티티는 영속 상태여야 한다.
//회원과 팀을 저장public void testSave(){ //팀1 저장 Team team1 = new Team("team1", "팀1"); em.persist(team1); //회원1 저장 Member member1 = new Member("member1", "회원1"); member1.setTeam(team1); //연관관계 설정 member1 -> team1 em.persist(member1); //회원2 저장 Member member2 = new Member("member2", "회원2"); member2.setTeam(team); //연관관계 설정 member2 -> team1 em.persist(member2);}
JPA는 참조하는 팀의 식별자(Team.id)를 외래키로 사용해서 적절한 등록 쿼리를 생성한다.
INSERT INTO TEAM (TEAM_ID, NAME) VALUES ('team1', '팀1');--외래키 값으로 탐조한 팀의 식별자가 입력됨INSERT INTO MEMBER (MEMBER_ID, NAME, TEAM_ID)VALUES ('member1', '회원1', 'team1');INSERT INTO MEMBER (MEMBER_ID, NAME, TEAM_ID)VALUES ('member2', '회원2', 'team1');
객체 그래프 탐색(객체 연관관계를 사용한 조회)member.getTeam()을 사용해서 member와 연관된 team 엔티티를 조회java Member member = em.find(Member.class, "member1"); Team team = member.getTeam(); //객체 그래프 탐색
객체지향 쿼리 사용(JPQL)
회원을 대상으로 조회하는데 팀1에 소속된 회원만 조회하려면 회원과 연관된 팀 엔티티를 검색 조건으로 사용해야 한다.
SQL은 연관된 테이블을 조인해서 검색조건을 사용하면 된다.
List<Member> resultList = em.createQuery(jpql, Member.class)
.setParameter("teamName", "팀1")
.getResultList();
for(Member member : resultList){
System.our.println("[query] member.username = "+ member.getUsername());
}
/*결과
[query] member.username = 회원1
[query] member.username = 회원2
*/
} `회원이 팀과 관계를 가지고 있는 필드를 통해서 Member와 Team을 조인했다. `FROM Member m JOIN m.team t` WHERE 절을 보면 조인한 `t.name`을 검색조건으로 사용해서 팀1에 속한 회원만 검색했다. (':'로 시작하는 것은 파라미터를 바인딩받는 문법이다.)`sql –실행되는 SQL SELECT M.* FROM MEMBER MEMBER INNER JOIN TEAM TEAM ON MEMBER.TEAM_ID = TEAM_.ID WHERE TEAM1_.NAME=‘팀1’ ```
//연관관계를 수정(em.update()같은 메소드 없음!)private static void updateRelation(EntityManager em){ //새로운 팀2 Team team2 = new Team("team2","팀2"); em.persist(team2); Member member = em.find(Member.class, "member1"); member.setTeam(team2);}
엔티티의 값만 변경해두면 트랜잭션을 커밋할 때 플러시가 일어나면서 변경 감지 기능이 작동되고 DB에 자동으로 반영한다.
//연관관계를 삭제private static void deleteRelation(EntityManager em){ Member member1 = em.find(Member.class, "member1"); member1.setTeam(null); //연관관계 제거}