em.merge 테스트 중에 이해가 되지 않는 현상이 있습니다.
156
작성한 질문수 1
안녕하세요. merge()에 대해서 의아한 부분이 있어서 질문드립니다. persist()하지 않은 객체의 경우 merge()를 했을 때, 어떤 결과가 나올까 궁금하여 테스트를 해보았습니다.
하지만, 예상했던 결과와는 다르게 동작하고 이런 부분이 이해되지 않기에 질문 드립니다.
[엔티티 상태]
Member엔티티(N)
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
@Column(name = "MEMBER_ID")
private Long id;
private String name;
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "TEAM_ID")
private Team team;
// 편의 메소드
public void addTeam(Team team) {
this.setTeam(team);
team.getMembers().add(this);
}
Team엔티티(1)
@Id
@GeneratedValue
@Column(name = "TEAM_ID")
private Long id;
private String name;
// 다대일 양방향
@OneToMany(mappedBy = "team")
private List<Member> members = new ArrayList<>();
Main1
public static void main(String[] args) {
EntityManagerFactory emf = Persistence.createEntityManagerFactory("hello");
EntityManager em = emf.createEntityManager();
EntityTransaction tx = em.getTransaction();
tx.begin();
try {
Team team = new Team();
team.setName("TeamA");
em.persist(team);
Member member = new Member();
member.setName("memberA");
member.addTeam(team);
em.persist(member);
em.flush();
em.clear();
/* em.merge() 테스트 */
Team teamB = new Team();
teamB.setName("TeamBB");
em.merge(teamB);
//em.persist(teamB);
System.out.println("merge한 엔티티가 영속성 컨텍스트에 있을까? "+em.contains(teamB)); // false (당연히 원래 컨텍스트에 없던 객체이므로)
Team findTeamB = em.find(Team.class, 3L); // 데이터가 DB에 존재함
System.out.println(findTeamB.getName()); // TeamBB
tx.commit();
} catch (Exception e) {
tx.rollback();
} finally {
em.close();
emf.close();
}
}
- teamB 데이터는 DB에 저장되어있습니다. (findTeamB.getName()이 TeamBB를 반환합니다.)
- teamB는 영속성 컨텍스트에는 존재하지 않습니다.
Main2
public static void main(String[] args) {
EntityManagerFactory emf = Persistence.createEntityManagerFactory("hello");
EntityManager em = emf.createEntityManager();
EntityTransaction tx = em.getTransaction();
tx.begin();
try {
/*Team team = new Team();
team.setName("TeamA");
em.persist(team);
Member member = new Member();
member.setName("memberA");
member.addTeam(team);
em.persist(member);
em.flush();
em.clear();*/
/* em.merge() 테스트 */
Team teamB = new Team();
teamB.setName("TeamBB");
em.merge(teamB);
//em.persist(teamB);
System.out.println("merge한 엔티티가 영속성 컨텍스트에 있을까? "+em.contains(teamB)); // false (당연히 원래 컨텍스트에 없던 객체이므로)
Team findTeamB = em.find(Team.class, 3L); // DB에 어떠한 team 데이터도 존재하지 않음
System.out.println(findTeamB.getName()); // 결과 없음
tx.commit();
} catch (Exception e) {
tx.rollback();
} finally {
em.close();
emf.close();
}
}
- team DB에 아무런 데이터도 존재하지 않습니다.
- 영속성 컨텍스트에 역시 teamB는 존재하지 않습니다.
- findTeamB.getName()의 결과는 없습니다. (3L의 키가 아닌것도 맞지만, DB에 애당초 아무런 데이터가 없음)
이렇게 Main1과 Main2의 동작에서 어떤 차이가 있기에 이런 결과를 보이는건지 알고싶습니다.
감사합니다.
답변 1
0
안녕하세요. 이동석님
tx.rollback(); 아래에 다음 코드를 추가해보시고 실행해보시면 문제를 찾을 수 있을거에요.
e.printStackTrace();
감사합니다.
변경감지(더티체킹) 이후 플러시할 경우의 쿼리
0
48
1
단일 테이블 시 null 값과 연관관계 필요성 질문
0
47
1
벌크연산에서 member.getAge 호출 시 영속성 컨텍스트에서 데이터를 가져오는건가요?
0
75
2
inheritance startegy 선택시 고려사항
0
51
1
Entity 동등성 비교
0
54
1
실무 조언 관련 질문입니다.
0
79
1
H2데이터베이스 파일 생성
0
92
2
서브쿼리 강의에서 ALL 예시 관련 질문드립니다.
0
74
2
수정또는 삭제시 영속성 엔티티에 값이 무조건 있어야 하나요?
0
74
1
JPQL 메소드와 락
0
68
1
Delivery @OneToOne
0
84
1
17강 4~5분대 테이블 값 조회가 안됩니다.
0
118
2
UnsupportedOperationException 발생
0
132
3
H2 Database 연결이 안됩니다.
0
117
2
연관관계 매핑 질문드립니다.
0
117
2
h2데이터베이스 실행오류
0
132
2
persistence.xml
0
137
2
양방향 연관관계에서 연관관계의 주인(mappedBy)을 왜 꼭 정해야 하나요?
0
106
1
영속성 컨텍스트
0
91
1
JPA 프록시
0
117
1
Native Query와 MyBatis
0
97
1
영속성 컨텍스트는 어떤 메모리에 저장되는건가요?
0
110
1
임베디드 타입 예시 코드 관련 질문
0
147
3
명시적 조인에서 별칭을 주면 왜 객체에 접근할 수 있나요
0
116
3





