일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | ||||
4 | 5 | 6 | 7 | 8 | 9 | 10 |
11 | 12 | 13 | 14 | 15 | 16 | 17 |
18 | 19 | 20 | 21 | 22 | 23 | 24 |
25 | 26 | 27 | 28 | 29 | 30 | 31 |
- ACCESS_REFUSED
- rabbitmq 에러
- 네임드 뷰
- $emit()
- 리액트
- REDIS
- 오라클 병렬처리
- paraller
- 오라클
- 트리 회전
- redux
- VUE
- 애그리거트
- 리덕스
- .getClass()
- forNmae()
- 리덕스 공식문서
- quert
- 도커빌드
- 자바
- 커스텀 로그인
- AWS
- Java Reflextion API
- 자료구조
- vue.js
- react
- 컴포넌트 주도
- Express
- EBS
- exiting abnormally
- Today
- Total
개발정리
JPA-다대일 연관관계 매핑 본문
일반적인 SQL에서는 외래키를 사용하여 두 릴레이션을 연관 시켜 줍니다.
이때, JOIN을 사용하여 두 테이블을 연결 시켜주므로 자동으로 양방향 연관관계가 됩니다.
하지만 JPA에서는 한쪽에만 관계를 설정하면 다른쪽에서는 참조를 할 수 없게 됩니다.
지금부터 TEAM엔티티와 MEMBER엔티티의 예제를 통해 설명 드리겠습니다.
@Entity
@Data
@Table
public class Team {
@Id @GeneratedValue(strategy = GenerationType.IDENTITY)
private Long team_id;
@Column(name = "TEAM_NAME")
private String teamName;
}
@Data
@Entity
@Table
public class Member {
@Id @GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@Column(name = "name")
private String name;
@ManyToOne
@JoinColumn(name = "team_id")
private Team team;
}
여러 member들은 team을 하나씩 가집니다.
member 입장에서는 manyToOne 관계가 됩니다.(많은 member들이 팀 하나를 가진다.)
public class Test {
public static void main(String[] args) {
EntityManagerFactory emf=Persistence.createEntityManagerFactory("hello");
EntityManager em=emf.createEntityManager();
try {
em.getTransaction().begin();
Team team1=new Team();
team1.setTeamName("1조");
em.persist(team1);
Team team2=new Team();
team2.setTeamName("2조");
em.persist(team2);
Member member1=new Member();
member1.setName("홍길동");
member1.setTeam(team1);
em.persist(member1);
Member member2=new Member();
member2.setName("이철수");
member2.setTeam(team2);
em.persist(member2);
em.getTransaction().commit();
}catch(Exception e) {
e.printStackTrace();
}finally {
emf.close();
}
}
}
1조와 2조 팀 테이블을 만들고 , member두명을 만들어 각각 팀을 할당 해주었습니다,
이제 여기에서 member의 team_id를 이용해 team_name을 불러와 봅시다.
em.getTransaction().begin();
Member member=em.find(Member.class,1L);
System.out.println(member.getTeam().getTeamName());
em.getTransaction().commit();
콘솔 창에 1조 라고 뜨는것을 보실 수 있습니다.
이 예제에서는 member객체를 불러와 team을 가져왔는데
반대로 team객체를 가져와 member를 불러 오려면 어떻게 해야 할까요?
@Entity
@Data
@Table
public class Team {
@Id @GeneratedValue(strategy = GenerationType.IDENTITY)
private Long team_id;
@Column(name = "TEAM_NAME")
private String teamName;
@OneToMany(mappedBy = "team")
private List<Member> memberList=new ArrayList<Member>();
}
team에 다음과 같이 memberList 속성을 생성하였습니다.
em.getTransaction().begin();
Team team1=new Team();
team1.setTeamName("1조");
em.persist(team1);
Team team2=new Team();
team2.setTeamName("2조");
em.persist(team2);
Member member1=new Member();
member1.setName("홍길동");
member1.setTeam(team1);
em.persist(member1);
Member member2=new Member();
member2.setName("이철수");
member2.setTeam(team2);
em.persist(member2);
em.getTransaction().commit();
em.getTransaction().begin();
Team team=em.find(Team.class, 1L);
List<Member> list=team.getMemberList();
System.out.println("리스트 사이즈:"+team.getMemberList().size());
for(Member member:list) {
System.out.println(member.getName());
}
em.getTransaction().commit();
다음과 같은 코드를 실행하면 리스트의 사이즈가 0인 걸 보실수 있습니다.
양방향 매핑이 되었다면 리스트의 사이즈는 1이여야 하지 않을까요?
그 이유는 현재 영속 컨텍스트에 저장되어 있는 객체를 가져왔기 때문 입니다.
영속 컨테이너에 저장되어있는 객체는 양방향 매핑이 되어있지않습니다.
public class Test {
public static void main(String[] args) {
EntityManagerFactory emf=Persistence.createEntityManagerFactory("hello");
EntityManager em=emf.createEntityManager();
try {
em.getTransaction().begin();
Team team1=new Team();
team1.setTeamName("1조");
em.persist(team1);
Team team2=new Team();
team2.setTeamName("2조");
em.persist(team2);
Member member1=new Member();
member1.setName("홍길동");
member1.setTeam(team1);
em.persist(member1);
Member member2=new Member();
member2.setName("이철수");
member2.setTeam(team2);
em.persist(member2);
em.getTransaction().commit();
em.clear();
em.getTransaction().begin();
Team team=em.find(Team.class, 1L);
List<Member> list=team.getMemberList();
System.out.println("리스트 사이즈:"+team.getMemberList().size());
for(Member member:list) {
System.out.println(member.getName());
}
em.getTransaction().commit();
}catch(Exception e) {
e.printStackTrace();
}finally {
emf.close();
}
}
}
다음과 같이 em.clear()를 실행하면 컨텍스트의 캐시가 초기화 되어 값이 제대로 나오는 것을 보실수 있습니다.
참조:JPA퀵스타트 , 채규태
'스프링 > JPA' 카테고리의 다른 글
JPA-다대다 매핑 (0) | 2023.09.02 |
---|---|
JPA-일대일 매핑 (0) | 2023.09.01 |
JPA-영속 컨텍스트 (0) | 2023.08.30 |
JPA-설정 (0) | 2023.08.29 |