사용자 도구

사이트 도구


java:hibernate:gotchas

문서의 이전 판입니다!


Hibernate/JPA Gotchas

하이버네이트/JPA에 관해 항상 기억해둬야 할 사항들을 정리해 둔다.

hashCode와 equals를 항상 구현한다

hashCode와 equals를 항상 구현해야 한다.

이때 DB 프라이머리키(ID)가 아닌 항상 변치 않고 해당 객체를 대표하는 의미를 가질 수 있는 비즈니스 키(business key)를 hashCode와 equals의 대상으로 삼아야 한다. 이유는 Set등에 신규 객체를 넣을 경우 신규 객체는 아직 프라이머리키가 지정되지 않은 상태이기 때문에 ID가 모두 null 혹은 0이며 이 경우 Set에 저장할 때 equals가 항상 true 여서 이전의 값을 뒤에 저장한 값이 계속 덮어써버리는 현상이 발생하기 때문이다.

따라서 ID를 equals/hashCode의 기준으로 삼을 경우 매우 주의해야 한다. 관련 참조 - Hibernate equals and hashCode

One-To-One 과 Many-To-One 관계를 조심하라

One-To-One과 Many-To-One 관계에서 One 측은 not null이라고 명시하지 않는이상 Lazy Loading이 작동하지 않는다. 이에 관해서는 JPA One-To-One을 참조한다.

toString 메소드를 조심하라

toString 메소드에서 레이지 로딩으로 지정된 필드를 출력하도록 해서 불필요하게 레이지 로딩 필드가 미리 읽혀지는 문제가 발생할 수 있다. toString 에서 출력값을 주의 깊게 선별해야 한다. 특히 lombok을 사용한다면 매우 주의하라.

OpenSessionInView 패턴 사용시 HTML 주석을 사용치 말라

toString 메소드에서와 같은 현상이 OpenSessionInView 패턴 사용시 뷰에서 발생할 수 있다. 더이상 필요없는 부분 특히 하이버네이트 도메인 객체를 호출하는 부분을 주석처리할 때 HTML 주석을 사용하지 말라. HTML주석은 서버사이드는 그대로 동작한다. 따라서 레이지 로딩으로 지정한 값을 HTML 주석 부분에서 호출하면 그대로 값이 로딩되어 출력된다.

항상 템플릿 엔진의 주석(JSP의 경우 <%– –%>)을 사용하라.

쿼리 로그를 남겨라

hibernate.show_sql=true
hibernate.format_sql=true

위 프라퍼티 옵션으로 쿼리 로그를 남길 수 있다. 그러나 hibernate.show_sql=false로 두고 되도록 Log4j 옵션을 사용하는 것이 좋다. Hibernate Log 남기기를 참조한다.

쿼리에 진짜로 ":"로 들어간다면?

Native SQL에 :를 넣어야 할 필요가 있다면 Escape을 해줘야 한다. java - How can I use MySQL assign operator(:=) in hibernate native query? \\: 형태로 Escape 한다.

SELECT k.`news_master_id` AS id, @ROW \\:= @ROW + 1 AS rownum 
    FROM keyword_news_list k 
    JOIN (SELECT @ROW \\:= 0) r 
    WHERE k.`keyword_news_id` = :kid
ORDER BY k.`news_master_id` ASC

Lazy 자식 컬렉션 2중 insert 문제(children collection insert twice)

참조

java/hibernate/gotchas.1423794756.txt.gz · 마지막으로 수정됨: 2015/02/13 11:32 저자 kwon37xi