Whiteship's Note

[하이버네이트 퀴즈] Flush

Hibernate/etc : 2009. 6. 24. 14:08


    @Transactional
    @Test
    public void crud() throws Exception {
        Emp emp = new Emp();
        emp.setName("ks");
        ed.save(emp);

        assertThat(ed.getAll().size(), is(1));
        assertThat(ed.get(emp.getId()).getName(), is("ks"));

        emp.setName("tb");
        ed.update(emp);
        assertThat(ed.get(emp.getId()).getName(), is("tb"));

        ed.delete(emp);
        assertThat(ed.getAll().size(), is(0));
    }

이런 테스트가 있는데, 콘솔 창에 쿼리를 봤더니.

Hibernate: insert into Emp (id, dept_id, name) values (null, ?, ?)
Hibernate: call identity()
Hibernate: select emp0_.id as id4_, emp0_.dept_id as dept3_4_, emp0_.name as name4_ from Emp emp0_
Hibernate: delete from Emp where id=?
Hibernate: select emp0_.id as id4_, emp0_.dept_id as dept3_4_, emp0_.name as name4_ from Emp emp0_

update문이 빠져있다. 여기서 발생하는 의문점이 한 두가지가 아니다.

1. DB에 update가 되지도 않았는데 테스트는 어떻게 통과한 것일까?

2. 왜 update 문은 날아가지 않은 것일까?

3. 역으로, 왜 insert와 delete는 날아간 것일까?

이 세 가지 의문을 해결하려면 위에서 작성한 코드를 좀 더 자세히 살펴볼 필요가 있다. 바로 ed.save(), ed.get(), ed.getAll(), ed.update(), ed.delete()  들이다. 이 녀석들이 어떻게 구현되어 있는지 보지 않고서는 알 수 없다. 또하나 Flush 모드 역시 알아야 한다.

- Flush 모드는 기본 모드인 AUTO를 사용했다.
- save(), get(), update(), delete()는 하이버네이트의 Session API와 동일하다고 생각하면 되며, getAll()은 다음과 비슷하게 구현되어 있다. session.createQuery("from Emp"); 실제로는 이 모든게 GenericDao 구현체에 들어있어서 약간 다르긴 하지만, 본질은 그렇다.
- 테스트는 @Transactional한 녀석으로 기본으로 rollback될 녀석이다.

자.. 이제 위 세가지 질문에 대답할 수 있을 것이다. 그랬다면, 다음 퀴즈도 덤으로 풀어보자.
update 쿼리를 볼 수 있는 방법은 현재 두 가지 정도가 떠오른다.

4. 위 테스트 코드에서 한 줄을 삭제하여 update 쿼리가 콘솔에 찍히게 해보자.

5. 위 코드에 ed.flush()를 어디에 추가하면 update문을 볼 수 있을까?

정답은 비공개.. 영원히..
top

  1. Favicon of http://igooo.org/tc BlogIcon igooo 2009.06.24 23:37 PERM. MOD/DEL REPLY

    emp.setName("tb";); 위에서 flush시키면 update가 나오기

    assertThat(ed.get(emp.getId()).getName(), is("ks";)); 지우면 update가 나타나지 않을까요?


    이클립스 설치하느라 실행은 못시켜봤습니다 .ㅎ

    Favicon of http://whiteship.me BlogIcon 기선 2009.06.25 08:33 PERM MOD/DEL

    안타깝게도.. 둘 다 땡입니다.

  2. koasu 2009.06.25 10:39 PERM. MOD/DEL REPLY

    4번: @Transactional 을 지우면 update 가 나타날꺼 같아요.
    5번: ed.update(emp); ed.flush(); 순으로 하면 update가 나타날꺼 같나요.

    Favicon of https://whiteship.tistory.com BlogIcon 기선 2009.06.25 11:02 신고 PERM MOD/DEL

    4번은 땡. 그거 없이 dao 테스트하기는 좀 그르치요. 당장엔 트랜잭션이 없다고 에러가 날 겁니다. 트랜잭션 설정을 롤백=false로 바꾼다 하더라도 결과는 마찬가지 입니다.

    5번은 맞추셨습니다.

  3. crystal 2009.06.25 11:34 PERM. MOD/DEL REPLY

    4. 위 테스트 코드에서 한 줄을 삭제하여 update 쿼리가 콘솔에 찍히게 해보자.
    // ed.delete(emp);


    5. 위 코드에 ed.flush()를 어디에 추가하면 update문을 볼 수 있을까?
    update()아래, delete()전

    Favicon of https://whiteship.tistory.com BlogIcon 기선 2009.06.25 11:41 신고 PERM MOD/DEL

    딩동댕!

  4. crystal 2009.06.25 11:38 PERM. MOD/DEL REPLY

    1. DB에 update가 되지도 않았는데 테스트는 어떻게 통과한 것일까?
    update전 emp객체가 컨택스트에 관리되는 객체, 즉 persistant 상태에 있기 때문이다.

    2. 왜 update 문은 날아가지 않은 것일까?
    아래 해당 객체의 delete가 있기 때문이다.

    Favicon of https://whiteship.tistory.com BlogIcon 기선 2009.06.25 11:41 신고 PERM MOD/DEL

    딩동댕~

Write a comment.




: 1 : ··· : 4 : 5 : 6 : 7 : 8 : 9 : 10 : 11 :