[DOC] Hibernate

Hibernate 란?

Hibernate에 관한 정의는 Hibernate Reference Documentation 에 보면 "Hibernate is an object/relational mapping tool for Java environments" 라고 정의하고 있습니다. 직역을 해보면 "Hibernate는 자바 환경을 위한 객체/관계형 매핑 도구이다".

여기서 object/relational mapping (ORM) 용어가 등장합니다. 참조 문서에 따른 정의에서 ORM은 객체 모형으로부터 SQL 기반의 스키마를 가진 관계형 데이터 모형으로 데이터 표현을 매핑하는 테크닉(technique of mapping a data representation from an object model to a relational data model with a SQL-based schema)이라고 설명하고 있습니다.
ORM에 대한 다른 정의를 볼까요. Hibernate In Action(Manning)에서는 "객체/관계형 매핑은 객체들과 데이터베이스 사이의 매핑을 설명하는 메타데이터를 사용함으로써, 자바 어플리케이션 내의 객체들을 관계형 데이터베이스에 있는 테이블로의 자동화된(그리고 투명한) 영속화이다."라고 정의하고 있네요.

Hibernate가 이렇게 어렵남? ? 물론 첨부터 ORM이라는 무거운 주제가 나와서 머리를 아프게 하겠지만, 일단은 이 주제를 통해 Hibernate가 무엇인지 더 잘 알 수 있으리라 생각됩니다.


ORM의 문제점들

많은 사람들이 ORM은 문제가 많아서 기피하는 이유를 말하곤 합니다. 'ORM 비슷한 거 한번 써 보았는데 맞지 않더라!'. 이런 말을 하면서 무엇이 문제인지를 제대로 얘기해 주지는 않더군요. 그래서 저는 이 기회에 ORM의 일반적인 문제점을 언급하는게 좋겠다고 생각됩니다.

(Hibernate In Action에서 발췌 번역...)
[우리가 O/R 매핑 문제점들이라고 일컫는 다음 쟁점들의 목록은 자바 환경에서 전체 객체/관계형 매핑 도구에 의해 해결되는 기본적인 문제점들이다. 특정 ORM 도구들은 특별한 기능(예를 들면 aggressive caching)을 제공할 수 있지만, 다음은 객체/관계형 매핑에 특징적인 개념적인 쟁점들에 관한 합리적으로 총망라한 목록이다:

1 영속 클래스들은 어떤 것인가? 그것들은 fine-grained 자바빈즈인가? 또는 그것들은 EJB와 같은 어떤(보다 거친) 컴포넌트 모형의 인스턴스들인가? 영속 도구는 어떻게 투명한가? 우리는 비즈니스 도메인의 클래스들에 대한 프로그래밍 모형과 컨벤션을 채택해야 하는가?

2 매핑 메타데이터는 어떻게 정의되는가? 객체/관계형 변환이 메타데이터에 의해 전체적으로 제어되므로, 이 메타데이터의 형식과 정의는 가장 중요한 쟁점이다. ORM 도구는 메타데이터를 그래픽으로 처리하기 위한 GUI를 지원하는가? 또는 메타데이터 정의에 대한 더 좋은 접근법들이 있는가?

3 우리는 클래스 상속 계층구조를 어떻게 매핑 해야 하는가? 몇가지 표준 방도들이 존재한다. 다형성 연관관계들, abstract 클래스들, 그리고 인터페이스들에 대해서는 어떠한가?

4 데이터베이스 (프라이머리 키) identity와 객체 identity와 equality를 어떻게 식별하는가? 우리는 특정 클래스들의 인스턴스들을 특정 테이블 행들로 어떻게 매핑 하는가?

5 영속 로직은 비즈니스 도메인의 객체들과 실시간으로 어떻게 상호작용하는가? 이것은 일반적인 프로그래밍의 문제점이고, 소스 생성, 런타임 reflection, 런타임 바이트코드 생성, 그리고 빌드시 바이트코드 증진을 포함하는 많은 솔루션들이 존재한다. 이 문제점에 대한 해결책은 빌드 과정에 영향을 줄 수 있다(그러나 그 밖의 경우 아마 사용자로서 당신에게 영향을 주지는 않을 것이다).

6 영속 객체의 생명주기란 무엇인가? 몇몇 객체들의 생명주기는 다른 연관된 객체들의 생명주기에 종속되는가? 객체의 생명주기를 데이터베이스 행의 생명주기로 변환할 수 있는가?

7 sorting, 검색, aggregating을 지원하는 편의들은 무엇인가? 어플리케이션은 메모리 내에서 이것들 중 어떤 것을 행할 수 있다. 그러나 관계형 기술의 효율적인 사용은 이 작업이 데이터베이스에 의해 수행될 것을 필요로 한다.

8 우리는 연관관계들을 가진 데이터를 어떻게 효율적으로 검색할 수 있는가? 관계형 데이터에 대한 효율적인 접근은 대개 테이블 조인들을 통해 달성된다. 객체-지향 어플리케이션들은 대개 객체 그래프를 네비게이트 함으로써 데이터에 접근한다. 다음 두 개의 데이터 액세스 패턴들은 가능하면 회피되어야 한다: n+1 개의 select 문제점, 그리고 그것의 보완물, Cartesian product 문제점(하나의 select 내에서의 너무 많은 데이터 페칭).


게다가 두 개의 쟁점들은 임의의 데이터-접근 기법에 공통적이다. 그것들은 또한 ORM의 설계와 아키텍처에 관한 기본적인 제약사항들을 노출시킨다:
■ 트랜잭션과 동시성
■ 캐시 관리(와 동시성)


당신이 볼 수 있듯이, 전체 객체 매핑 도구는 긴 쟁점들의 목록을 제기하는 것을 필요로 한다.]


위의 문제점들은 ORM 도구들이 해결할 영역들인데, 이들 문제점들을 잘 해결하는 그러한 ORM 도구를 채택할 것이고, 필자는 그런 도구들 중에서 Hibernate를 선택하였습니다.


ORM의 이점들

ORM 도구들의 이점들이 무엇인지를 살펴보죠.

(Hibernate In Action에서 발췌 번역... )

[ ORM의 가정된 장점은 그것이 "성가신" SQL로부터 개발자들을 "은폐"시켜 준다는 점이다. 이 견해는 객체 지향 개발자들이 SQL이나 관계형 데이터베이스를 잘 이해할 것을 기대할 수 없고 그들이 SQL이 다소 불쾌함을 발견한다는 점을 견지한다. 반대로, 우리는 자바 개발자들은 ORM으로 작업하기 위해서 관계형 모델링과 SQL에 충분한 레벨의 숙력도-와 이해도-를 가져야 한다고 믿는다. ORM은 이미 그것을 어려운 방법으로 행해 보았던 개발자들에 의해 사용될 개선된 테크닉이다. Hibernate를 효과적으로 사용하기 위해서, 당신은 SQL 문장을 보고 해석할 줄 알아야 하고 퍼포먼스와 관련된 것을 이해할 줄 알아야 한다. ORM과 Hiberante의 이점들 중 몇몇을 살펴보자.
생산성
영속 관련 코드는 아마 자바 어플리케이션에서 가장 지루한 코드일 수 있다. Hibernate는 (당신이 예상하는 것 이상의) 꿀꿀대는 작업량을 제거해주고 당신이 비지니스 문제에 집중하도록 해준다. 당신이 좋아하는 어플리케이션 개발 방도가 어느 것이든-도메인 모형으로부터 시작하는 top-down이든; 존재하는 데이터베이스 스키마로부터 시작하는 bottom-up이든- 상관없이, 적절한 도구들과 함께 사용되는 Hibernate는 개발 시간을 현저하게 감축시켜줄 것이다.
Maintainability
더 적은 코드 라인들(lines of code, LOC)은 시스템을 보다 더 이해가능하도록 만들어 준다. 왜냐하면 그것은 배관공사가 아닌 비지니스 로직을 강조하기 때문이다. 가장 중요하게 더 적은 코드를 가진 시스템은 리팩토링하기가 더 쉽다. 자동화 된 객체/관계형 영속화는 대체로 LOC를 감소시킨다. 물론 코드 라인들의 개수는 어플리케이션 복잡성을 측량하는 논쟁의 여지가 있는 방법이다. 하지만 Hibernate 어플리케이션이 보다 유지관리 가용적이라는 점에 대한 다른 이유들이 존재한다.
수작업 코드화 된 영속을 가진 시스템에서, 부득이한 긴장이 관계형 표상과 도메인을 구현하는 객체 모형 사이에 존재한다. 한 쪽에 대한 변경들은 항상 다른 쪽에 대한 변경들을 수반한다. 그리고 종종 하나의 표상에 대한 설계는 다른 것의 존재에 적응하도록 절충적이다.(실전에서 항상 발생하는 것은 도메인의 객체 모형이 양보되어야 한다는 점이다.) ORM은 자바 측의 객체 지향성을 보다 강력한 사용을 허용하고, 다른 변경들로의 마이너 변경으로부터 각각의 모형을 격리시킴으로서, 두 모형들 사이에 버퍼를 제공한다.
Performance
공통된 주장은 수작업 코드화된 영속은 항상 적어도 가장 빠를 수 있고, 흔히 자동화 된 영속화 보다도 더 빠를 수 있다. 어셈블리 코드가 항상 자바 바이트 코드보다 더 빠를 수 있거나, 수작업으로 작성된 파서가 YACC또는 ANTLR에 의해 생성된 파서 보다 더 빠를 수 있다는 점이 참이라는 의미에서 이것은 참이다. 그 주장의 말하지 않은 암시는 수작업 코드화 된 영속은 적어도 실제 어플리케이션에서 만큼은 잘 수행될 것이다. 그러나 이 함축은 적어도 가장 빠른 수작업 코드화 된 영속성이 자동화 된 솔루션을 활용하는데 수반된 노력의 양과 유사한 만큼 구현될 것을 요구할 경우에만 참이 될 것이다. 진정으로 흥미로운 질문은 우리가 시간과 예산 제약을 고려할 때 무엇이 발생하는가?이다. 주어진 영속성의 태스크에 대해 많은 최적화들이 가능하다. (질의 힌트들과 같은) 어떤 것은 수작업 코드화 된 SQL/JDBC로 성취하는 것이 훨씬 더 쉽다. 하지만 대부분의 최적화들은 자동화 된 ORM으로 성취하는 것이 훨씬 더 쉽다. 시간 제약을 가진 프로젝트에서, 수작업 코드화 된 영속은 대개 당신이 어떤 최적화를 행하는데 많은 시간을 소요하게 한다. Hibernate는 사용될 수 있는 전체 시간 내에서 더 많은 최적화를 허용해준다. 게다가 자동화 된 영속은 당신이 새로운 남아 있는 병목현상들을 수작업 최적화 하는데 더 많은 시간을 할애할 수 있도록 개발자의 생산성을 개선시켜준다. 마지막으로 당신의 ORM 소프트웨어를 구현했던 사람들은 아마 당신이 투자했던 것보다 더 많은 시간을 퍼포먼스에 투자했다. 예를 들어 당신은 풀링 인스턴스들이 DB2/JDBC 드라이버에 대해 현저한 퍼포먼스 증가로 귀결되지만 InterBase JDBC 드라이버는 그렇지 못하다는 점을 알고 있는가? 당신은 테이블의 변경된 컬럼들만을 업데이트 하는 것이 몇몇 데이터베이스들에 대해 현저하게 더 빠를 수 있지만 다른 데이터베이스들에 대해서는 잠정적으로 더 느려진다는 점을 체험했는가? 당신의 수작업 솔루션에서, 이들 다양한 방도들의 영향을 실험하는 것이 얼마나 쉬운가?
벤더 독립성
ORM은 기본 SQL 데이터베이스와 SQL dialect로부터 당신의 어플리케이션을 추상화 시킨다. 만일 도구가 많은 다른 데이터베이스들을 지원할 경우, 이것은 당신의 어플리케이션에 대한 어떤 수준의 이식성을 수여한다. 당신은 반드시 write once/run anywhere를 필요로 하지 않을 것이다. 왜냐하면 데이터베이스들의 가용성들이 차이가 나고 전체적인 이식성을 성취하는 것은 보다 강력한 플랫폼들의 어떤 강도를 제물로 삼을 것을 필요로 할 것이다. 그럼에도 불구하고, 대개 ORM을 사용하여 크로스 플랫폼 어플리케이션을 개발하는 것이 훨씬 더 쉽다. 만일 당신이 크로스 플랫폼 오퍼레이션을 필요로 하지 않을 경우조차도, ORM은 여전히 벤더 잠금과 연관된 리스크들 중 몇몇을 완화 시키는데 도움이 될 수 있다. 게다가 데이터베이스 독립성은 개발자들이 경량급 로컬 데이터베이스를 사용하지만 다른 데이터베이스 상에 제품을 배치하는 개발 시나리오에서 도움을 준다. ]

이제 ORM을 왜 도입하는가에 대한 어느 정도 설명이 되었겠죠.

앞서 언급한 대로 Hibernate는 많은 ORM 도구들 중 하나입니다. 물론 각자의 취향에 따라 또는 프로젝트의 필요에 따라 각각의 ORM 도구들을 다르게 사용하겠지만, 여기서 다른 도구들은 관심의 범위를 벗어난 것이라 언급하지 않고 Hibernate에 보다 집중하도록 하겠습니다.

댓글

이 블로그의 인기 게시물

[LINUX] CentOS 부팅시 오류 : UNEXPECTED INCONSISTENCY; RUN fsck MANUALLY

[MSSQL] 데이터베이스가 사용 중이어서 배타적으로 액서스할 수 없습니다

구글코랩) 안전Dream 실종아동 등 검색 오픈API 소스를 공유합니다. (구글드라이브연동, 이미지 수집 소스)