hibernate-orm/doc/reference/ko/modules/architecture.xml

309 lines
20 KiB
XML
Raw Normal View History

<chapter id="architecture">
<title>아키텍처</title>
<sect1 id="architecture-overview" revision="1">
<title>개요</title>
<para>
Hibernate 아키텍처에 대한 (매우) 높은 수준의 개요::
</para>
<mediaobject>
<imageobject role="fo">
<imagedata fileref="images/overview.svg" format="SVG" align="center"/>
</imageobject>
<imageobject role="html">
<imagedata fileref="../shared/images/overview.gif" format="GIF" align="center"/>
</imageobject>
</mediaobject>
<para>
이 다이어그램은 어플리케이션에 영속화 서비스들(과 영속 객체들)을 제공하기 위해 데이터베이스와
컨피그레이션을 사용하는 Hibernate를 보여준다.
</para>
<para>
우리는 런타임 아키텍처에 대한 보다 상세한 뷰를 보여주고 싶다. 불행하게도, Hibernate는 유연하며
몇 가지 접근법들을 제공한다. 우리는 두 가지 극단을 보여줄 것이다. "경량급" 아키텍처는 그것 자신의
JDBC 커넥션들을 제공하고 그것 자신의 트랜잭션들을 관리하는 어플리케이션을 갖는다. 이 접근법은
Hibernate의 API의 최소 부분집합을 사용한다:
</para>
<mediaobject>
<imageobject role="fo">
<imagedata fileref="images/lite.svg" format="SVG" align="center"/>
</imageobject>
<imageobject role="html">
<imagedata fileref="../shared/images/lite.gif" format="GIF" align="center"/>
</imageobject>
</mediaobject>
<para>
"전체 정수" 아키텍처는 기본 JDBC/JTA로부터 어플리케이션을 추상화 시키고 Hibernate로 하여금
상세한 것을 처리하게 한다.
</para>
<mediaobject>
<imageobject role="fo">
<imagedata fileref="images/full_cream.svg" format="SVG" align="center"/>
</imageobject>
<imageobject role="html">
<imagedata fileref="../shared/images/full_cream.gif" format="GIF" align="center"/>
</imageobject>
</mediaobject>
<para>
다음은 다이어그램들 내에 있는 객체들에 대한 몇가지 정의들이다:
<variablelist spacing="compact">
<varlistentry>
<term>SessionFactory (<literal>org.hibernate.SessionFactory</literal>)</term>
<listitem>
<para>
단일 데이터베이스에 대한 컴파일된 매핑들의 threadsafe (불변의) 캐시. Session과 ConnectionProvider의
클라이언트를 위한 팩토리. 프로세스 레벨 또는 클러스터 레벨에서 트랜잭션들 사이에 재사용 가능한 데이터의 선택적인
(second-level) 캐시를 보관할 수도 있다.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>Session (<literal>org.hibernate.Session</literal>)</term>
<listitem>
<para>
어플리케이션과 영속 저장소 사이의 대화를 표현하는 단일 쓰레드이고, 수명이 짧은 객체. JDBC 커넥션을 포장한다.
<literal>Transaction</literal> 용 팩토리. 객체 그래프를 네비게이트 하거나 식별자로 객체들을 룩업할 때
사용되는 영속 객체들에 대한 필수적인(첫 번째 레벨의) 캐시를 보관한다.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>영속 객체들과 콜렉션들</term>
<listitem>
<para>
persistent 상태와 비지니스 기능을 포함하는 수명이 짧고, 단일 쓰레드인 객체들. 이것들은 통상의 JavaBeans/POJO들일
수 있고, 오직 그것들에 대한 오직 특별한 것은 그것들이 현재 (정확하게 한 개의) <literal>Session</literal>과 연관되어
있다는 점이다. <literal>Session</literal>이 닫히자마자, 그것들은 분리될(detached 상태가 될) 것이고 어플리케이션
레이어에서 사용하는 것이 자유로와진다(예를 들면. 직접적으로 프리젠테이션 계층으로
데이터 전송 객체들로서 그리고 직접적으로 프리젠테이션 계층으로부터 데이터 전송 객체들로서).
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>전이(Transient, 필자 주-과도) 객체들과 콜렉션들</term>
<listitem>
<para>
<literal>Session</literal>과 현재 연관되어 있지 않은 영속 클래스들의 인스턴스들. 그것들은 어플리케이션에 의해 초기화
되었고 (아직) 영속화 되지 않았거나 그것들은 닫혀진<literal>Session</literal>에 의해 초기화 되었을 수도 있다.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>Transaction (<literal>org.hibernate.Transaction</literal>)</term>
<listitem>
<para>
(옵션) 작업의 원자 단위를 지정하기 위해 어플리케이션에 의해 사용되는 단일 쓰레드이고, 수명이 짧은 객체. 기본 JDBC, JTA
또는 CORBA 트랜잭션으로부터 어플리케이션을 추상화 시킨다. 몇몇 경우들에서 하나의 <literal>Session</literal>
여러 개의 <literal>Transaction</literal>들에 걸칠 수 있다. 하지만 기본 API 또는 <literal>Transaction</literal>
사용하는 트랜잭션 경계 설정은 결코 옵션이 아니다!
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>ConnectionProvider (<literal>org.hibernate.connection.ConnectionProvider</literal>)</term>
<listitem>
<para>
(옵션) JDBC 커넥션들에 대한 팩토리(그리고 그것들의 pool). 기본 <literal>Datasource</literal> 또는
<literal>DriverManager</literal>로부터 어플리케이션을 추상화 시킨다. 어플리케이션에 노출되지는 않지만
개발자에 의해 확장/구현 된다.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>TransactionFactory (<literal>org.hibernate.TransactionFactory</literal>)</term>
<listitem>
<para>
(옵션) <literal>Transaction</literal> 인스턴스들에 대한 팩토리. 어플리케이션에 노출되지는 않지만 개발자에 의해
확장/구현 된다.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><emphasis>Extension Interfaces</emphasis></term>
<listitem>
<para>
Hibernate는 당신의 영속 계층의 특성을 맞춤화 시키기 위해 당신이 구현할 수 있는 선택적인 확장 인터페이스들을 제공한다.
상세한 것은 API 문서를 보라.
</para>
</listitem>
</varlistentry>
</variablelist>
</para>
<para>
주어진 "경량급" 아키텍처의 경우, 어플리케이션은 JTA 또는 JDBC와 직접 대화하기 위해서 <literal>Transaction</literal>/<literal>TransactionFactory</literal>
그리고/또는 <literal>ConnectionProvider</literal> API들을 무시한다.
</para>
</sect1>
<sect1 id="architecture-states" revision="1">
<title>인스턴스 상태들</title>
<para>
영속 클래스들의 인스턴스는 세개의 상태들 중 하나 일 수 있다. 그것들(상태들)은 영속 컨텍스트(<emphasis>persistence context</emphasis>)에
대해 정의된다. Hibernate <literal>Session</literal> 객체는 영속 컨텍스트이다:
</para>
<variablelist spacing="compact">
<varlistentry>
<term>transient</term>
<listitem>
<para>
인스턴스는 임의의 컨텍스트와 연관되어 있지 않고, 결코 연관된 적이 없었다. 그것은 영속 식별자(프라이머리 키 값)을 갖지 않는다.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>persistent</term>
<listitem>
<para>
인스턴스는 현재 영속 컨텍스트와 연관되어 있다. 그것은 영속 식별자(프라이머리 키 값) 그리고 아마 데이터베이스 내에 있는 대응하는
행을 갖는다. 특별한 영속 컨텍스트의 경우, Hibernate는 영속 identity가 Java identity(객체의 메모리 내 위치)와 같다는 점을
<emphasis>보증한다</emphasis>.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>detached</term>
<listitem>
<para>
인스턴스는 영속 컨텍스트와 한번 연관되었지만, 그 컨텍스트가 닫혔거나, 그 인스턴스가 또 다른 프로세스로 직렬화 되었다. 그것은 영속
identity 그리고, 아마 데이터베이스 내에 대응하는 행을 갖는다. detached 인스턴스들의 경우, Hibernate는 영속 identity과
Java identity 사이의 관계를 보증하지 않는다.
</para>
</listitem>
</varlistentry>
</variablelist>
</sect1>
<sect1 id="architecture-jmx" revision="1">
<title>JMX 통합</title>
<para>
JMX는 자바 컴포넌트 관리를 위한 J2EE 표준이다. Hibernate는 JMX 표준 서비스를 통해 관리될 수도 있다. 우리는 배포본 내에 MBean 구현,
<literal>org.hibernate.jmx.HibernateService</literal>를 제공한다.
</para>
<para>
JBoss 어플리케이션 서버 상에 Hibernae를 JMX 서비스로서 배치하는 방법에 대한 예제는 JBoss 사용자 가이드를 보길 바란다. JBoss
어플리케이션 서버 상에서, 만일 당신이 JMX를 사용하여 배치할 경우 당신은 또한 다음 이점들을 얻는다:
</para>
<itemizedlist>
<listitem>
<para>
<emphasis>Session 관리:</emphasis> Hibernate <literal>Session</literal>의 생명주기가 JTA 트랜잭션의
영역 내에 자동적으로 바인드 될 수 있다. 이것은 당신이 더이상 <literal>Session</literal>을 수작업으로 열고 닫지 않아도
됨을 의미하고, 이것은 JBoss EJB 인터셉터의 업무가 된다. 당신은 또한 더 이상 당신의 코드 어느 곳에서든 트랜잭션 경계설정에
대해 걱정하지 않아도 된다(당신이 물론 이식성 있는 영속 계층을 작성하고자 원하지 않는한, 이를 위해 옵션 Hibernate <literal>Transaction</literal>
API를 사용하라). 당신은 <literal>Session</literal>에 접근하기 위해 <literal>HibernateContext</literal>를 호출한다.
</para>
</listitem>
<listitem>
<para>
<emphasis>HAR 배치:</emphasis> 대개 당신은 JBoss 서비스 배치 디스크립터를 사용하여 Hibernate JMX 서비스를
(EAR 과/또는 SAR 파일로) 배치하고, 그것은 Hibernate <literal>SessionFactory</literal>의 통상적인 구성
옵션들 모두를 지원한다. 하지만 당신은 여전히 모든 당신의 매핑 파일들을 배치 디스크립터 속에 명명해야 한다. 만일 당신이
옵션 HAR 배치를 사용하고자 결정하는 경우, JBoss는 당신의 HAR 파일 내에 있는 모든 매핑 파일들을 자동적으로 검출해낼 것이다.
</para>
</listitem>
</itemizedlist>
<para>
이들 옵션들에 대한 추가 정보는 JBoss 어플리케이션 서버 사용자 가이드를 참조하라.
</para>
<para>
JMX 서비스로서 이용 가능한 또다른 특징은 런타임 Hibernate 통계이다.
<xref linkend="configuration-optional-statistics"/>를 보라.
</para>
</sect1>
<sect1 id="architecture-jca" revision="1">
<title>JCA 지원</title>
<para>
Hibernate는 JCA 커넥터로서 구성될 수도 있다. 상세한 것은 웹 사이트를 보길 바란다. Hibernate JCA 지원은 여전히 실험적으로
검토 중에 있음을 노트하길 바란다.
</para>
</sect1>
<sect1 id="architecture-current-session" revision="2">
<title>컨텍스트 상의 세션들</title>
<para>
Hibernate를 사용하는 대부분의 어플리케이션들은 어떤 양식의 "컨텍스트상의(contextual)" 세션들을 필요로 한다. 여기서
주어진 세션은 주어진 컨텍스트의 영역에 걸쳐 활동을 한다. 하지만 어플리케이션들을 가로질러 컨텍스트를 구성하는 것에 대한 정의는
일반적으로 다르다; 그리고 다른 컨텍스트들은 현재라고 하는 개념에 대해 다른 영역들을 정의한다. 버전 3.0 전의 Hibernate를
사용하는 어플리케이션들은 자가생산된 <literal>ThreadLocal</literal>-기반의 컨텍스상의 세션들,
<literal>HibernateUtil</literal>과 같은 helper 클래스들을 활용했거나
프락시/인터셉션 기반의 컨텍스트상의 세션들을 제공해주었던 (Spring 또는 Pico와 같은 )제 3의 프레임웍들을 활용하는 경향이 있었다.
</para>
<para>
버전 3.0.1에서부터 시작하여, Hibernate는 <literal>SessionFactory.getCurrentSession()</literal> 메소드를
추가했다. 초기에 이것은 <literal>JTA</literal> 트랜잭션들을 사용하는 것을 전제했다. 여기서 <literal>JTA</literal>
트랜잭션은 현재 세션의 영역과 컨텍스트를 정의했다. Hibernate 팀은 성숙된 다수의 스탠드얼론 <literal>JTA TransactionManager</literal>
구현들이 발표되면, (전부는 아니겠지만) 대부분의 어플리케이션들이 그것들이 <literal>J2EE</literal> 컨테이너 내로 배치되든
그렇지 않든 간에 <literal>JTA</literal> 트랜잭션 관리를 사용하게 될 것이라고 주장한다. 그것에 기초하여, <literal>JTA</literal>에 기반한
컨텍스트상의 세션들은 언젠가 당신이 사용을 필요로 하게 될 전부다.
</para>
<para>
하지만 버전 3.1 이후로 <literal>SessionFactory.getCurrentSession()</literal> 이면의 처리과정은
이제 플러그 가능하다. 그것을 끝내기 위해, 하나의 새로운 확장 인터페이스
(<literal>org.hibernate.context.CurrentSessionContext</literal>)와
하나의 새로운 구성 파라미터(<literal>hibernate.current_session_context_class</literal>)가 현재 세션들을
정의하는 영역과 컨텍스트의 플러그 가능성을 허용하기 위해 추가되었다.
</para>
<para>
그것의 계약에 대한 상세한 논의는 <literal>org.hibernate.context.CurrentSessionContext</literal> 인터페이스에
관한 javadocs를 보라. 그것은 하나의 메소드, <literal>currentSession()</literal>를 정의하며, 그 구현은
현재의 컨텍스트 상의 세션을 추적할 책임이 있다. 비공식적으로, Hibernate는 이 인터페이스에 대한 세 개의 구현들을 부수적으로
포함하고 있다.
</para>
<itemizedlist>
<listitem>
<para>
<literal>org.hibernate.context.JTASessionContext</literal> - 현재의 세션들은 하나의
<literal>JTA</literal>에 의해 추적되고 영역화 된다. 여기서 처리과정은 이전의 JTA-전용 접근과 정확하게
동일하다. 상세한 것은 javadocs를 보라.
</para>
</listitem>
<listitem>
<para>
<literal>org.hibernate.context.ThreadLocalSessionContext</literal> - 현재의 세션들은
실행 쓰레드에 의해 추적된다. 상세한 것은 다시 javadocs를 보라.
</para>
</listitem>
</itemizedlist>
<para>
처음의 두 구현들은 <emphasis>session-per-request</emphasis>로 알려지고 사용되고 있는
"하나의 세션 - 하나의 데이터베이스 트랜잭션" 프로그래밍 모형을 제공한다. 하나의 Hibernate 세션의 시작과 끝은
데이터베이스 트랜잭션의 존속 기간에 의해 정의된다. 만일 (예를 들면 순수 J2SE에서 또는 JTA/UserTransaction/BMT의 경우에)
당신이 프로그램 상의 트랜잭션 경계구분을 사용할 경우, 당신은 당신의 코드로부터 기본 트랜잭션 시스템을 은폐시키는데
Hibernate <literal>Transaction</literal> API를 사용하는 것이 권장된다. 만일 당신이 CMT를 지원하는
하나의 EJB 컨테이너에서 실행할 경우, 트랜잭션 경계들이 선언적으로 정의되고 당신은 당신의 코드 내에 어떤 트랜잭션도
세션 경계구분 오퍼레이션들을 필요로 하지 않는다. 추가 정보와 코드 예제들은 <xref linkend="transactions"/>를 참조하라.
</para>
<para>
<literal>hibernate.current_session_context_class</literal> 구성 파라미터는
<literal>org.hibernate.context.CurrentSessionContext</literal> 구현이 사용될 것임을 정의한다. 역호환을 위해.
만일 이 구성 파라미터가 설정되지 않았지만 하나의 <literal>org.hibernate.transaction.TransactionManagerLookup</literal>
구성되어 있을 경우, Hibernate는 <literal>org.hibernate.context.JTASessionContext</literal>를 사용할 것임을
노트하라. 일반적으로, 이 파라미터의 값은 단지 사용할 구현 클래스를 명명할 것이다; 하지만 두 가지 비공식적인 구현들로서 두 개의
대응하는 짧은 이름들 "jta"와 "thread"이 존재한다.
</para>
</sect1>
</chapter>