작성
·
129
0
안녕하세요. 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();
감사합니다.