요약
JPA/Hibernate는 Java 코드에서 더 이상 SQL을 쓸 필요가 없다는 이유로 많이 쓰이는 프레임워크가 되었습니다. 하지만, 저는 새 프로젝트에 이를 사용하지 말아야 한다고 주장하고 싶습니다.
이유
매우 긴 공식 문서
공식 문서를 pdf로 변환하면 무려 406쪽이나 되는데, 이는 반지의 제왕(231쪽), SQL 표준 문서(288쪽)보다 큽니다. 데이터베이스 쿼리를 익히기 위해 석사 과정을 밟을 필요는 없습니다.
가변성
- 어떤 엔티티가 한 요소를 필요로 한다 해도, 아무 인자도 없는 생성자를 강요합니다.
- 엔티티 클래스에
final,abstract키워드를 넣음으로써, 상속을 방지할 수 없습니다. - Reflection/Introspection은 OOP의 캡슐화 원칙을 무시합니다.
- 누군가가 악의적인 코드를 심어 데이터를 완전히 날릴 수 있습니다.
지연 로딩 및 캐시
@Lazy어노테이션은 초심자에게 있어 가장 최악의 기술입니다. 하지만 도메인 설계가 Hibernate와 맞지 않거나 쿼리를 작성할 수 없을 때 이를 피할 수 없습니다.- 캐시 메커니즘은 이해하기 어렵습니다. 게다가 이해했다 해도 쿼리 결과가 아닌 엔티티 자체를 캐시에 저장해야 합니다.
메모리-데이터베이스 동기화(Flush)
Flush라는 기술은 메모리에 저장된 객체와 데이터베이스를 동기화합니다. 이는 두 문제를 야기합니다.
- Flush가 작동하면 메모리 안의 편집이 끝나버리기 때문에, Hibernate가 아닌 다른 영속성 도구는 꿈도 꿀 수 없으며,
- Flush 도중 충돌이 발생하면 코드와 상관 없는 Stack Trace 오류가 발생할 수 있습니다.
한 테이블의 특정 칼럼만 얻기
어떤 엔티티 중 한 칼럼만 접근하고 싶으면 SQL의 접근 방식은 다음과 같이 단순합니다.
select url from image
where id = 'F462E8D9-9DF7-4A58-9112-EDE0434B4ACE';
하지만 Hibernate는 무조건 엔티티의 모든 칼럼을 조회합니다. 이를 피하려면 복잡한 과정을 거쳐야 합니다.
칼럼에 대한 제한 사항(Constraint) 정의
어느 한 칼럼에 대한 제한 사항을 정의하기 위해 아래처럼 여러 어노테이션을 붙여야 합니다.
...
@NotNull
@NotEmpty
@Email
private String email;
...
이 방식은 다음과 같은 문제를 야기합니다.
- 이 조건을 위해 단위 테스트를 할 수 없습니다.
- Flush 작업을 하는 동안 이 처리 과정을 파악하기엔 너무 늦습니다.
- 나올 수 있는 예외는 일반적이고, 쓸모 없습니다.
- 비즈니스 규칙을 기술적인 규칙으로만 다룹니다.
전략에 대한 문제
- 프레임워크는 업데이트가 최악이고, 하위 호환성을 무시, 무조건적으로 의존하게 만듭니다. 이를 만드는 회사는 독점하기 위해 자신의 프레임워크를 쓰는 것이 당연하다고 여기게 만듭니다. 이 악순환은 막아야 합니다.
- 개념 증명(Proof of Concept)을 굳이 프레임워크를 통해야만 얻는 것은 자신의 시야를 좁히는 결과만 얻을 것이며, 특히 JPA/Hibernate의 경우는 더더욱 그렇습니다. 티끌만큼도 허용해선 안 됩니다.
어떻게 해야 할까요?
SQL을 쓰세요
SQL만으로 모든 것이 가능합니다. 모든 프로그래머가 알고, 쿼리가 직관적이고, 프레임워크가 필요 없습니다.
관리자가 Hibernate를 쓰라는데요?
퇴사하시거나, 코드를 프레임워크와 분리하는 작업을 하세요.
이미 사용 중이라면...
- 기본 생성자와 설정자의 공개 수준을
public으로 만들지 마세요. - SQL이 생성하는 아이디 대신 UUID같은 문자열을 쓰세요.
XXXRepository라는 이름 대신XXXDao라는 이름을 쓰세요.@SequenceGenerator어노테이션을 쓰지 마세요.- 도메인 클래스와 DAO 클래스를
intarface로 분리하세요. - *대다 관계(
@OneToMany등)를 쓰지 마시고, 차라리 엔티티 맵핑을 피하세요.
결론
JPA/Hibernate, 버리세요.
- 비즈니스 문제를 해결할 더 짧고 좋은 문서가 있습니다.
- 설계를 너무 빠른 방식으로만 고수하지 마세요.
- 당신의 코드를 관리할 다음 개발자에게 관용을 베푸세요.
여러분은 무엇을 사용하시나요?
- JPA/Hibernate
- 다른 ORM 기술