2장. 셋업과 구성

TODO: persistence.xml과 .pars에 대한 보다 깊은 지원이 전체적으로 완료될 때 이 절을 개정할 것.

2.1. 셋업

EJB3 호환 Hibernate EntityManager는 Hibernate 알맹이(core)와 Hibernate Annotations의 상단에서 빌드된다. 당신은 각각의 모듈에 대한 호환가능한 버전들을 사용해야 한다 - EntityManager의 배포본 패키지 내에 있는 README.TXT 파일을 보라. 다음 라이브러리들은 당신의 classpath 내에 있어야 한다: hibernate3.jar, hibernate-annotations.jar, hibernate-entity-manager.jar 그리고 각각의 패키지에 대해 모든 필요한 제 3의 라이브러리들.(ejb-persistence.jar를 포함하여).

2.2. 구성

어플리케이션 서버 내에서 그리고 스탠드얼론 어플리케이션 내에서 엔티티 관리자들에 대한 구성은 하나의 영속 아카이브(persistence archive, .par) 내에 존재한다. 하나의 영속 아카이브는 .jar 대신에 .par 접미사를 가진 하나의 JAR 파일이다. 당신은 또한 .par 파일의 META-INF 폴더 내에 존재하는 한 개의 persistence.xml 파일을 정의해야 한다. 다음은 persistence.xml 파일에 대한 예제이다.

<entity-manager>
   <name>manager1</name>
   <provider>org.hibernate.ejb.HibernatePersistence</provider>
   <jta-data-source>java:/DefaultDS</jta-data-source>
   <mapping-file>ormap.xml</mapping-file>
   <jar-file>MyApp.jar</jar-file>
   <class>org.acme.Employee</class>
   <class>org.acme.Person</class>
   <class>org.acme.Address</class>
   <properties>
      <property name="hibernate.dialect" value="org.hibernate.dialect.HSQLDialect"/>
      <property name="hibernate.hbm2ddl.auto" value="create-drop"/>
   </properties>
</entity-manager>
     
name

모든 엔티티 관리자는 한 개의 name을 가져야 한다. 만일 name이 지정되지 않을 경우, .par 파일의 이름에서 .par 접미사를 빼고 사용된다. Hiberante EntityManager의 현재 구현은 당신이 name 요소를 정의하는 것을 필요로 한다.

provider

provider는 EJB 영속 공급자에 대한 전체 수식된 클래스 이름이다. 당신은 그것이 Hibernate에 대한 디폴트가 될 것으로서 이것을 집어 넣지 말아야 한다. 이것은 당신이 EJB 영속에 대한 여러 벤더 구현들을 사용할 때 필요하다.

jta-data-source, non-jta-data-source

이것은 javax.sql.DataSource가 위치해 있는 JNDI 이름이다. 어플리케이션 서버 내에서 사용되지 않을 때 이것은 무시된다. 어플리케이션 외부에서 실행될 때, 당신은 Hibernate에 특정한 프로퍼티들을 가지고 JDBC 커넥션들을 지정해야 한다(아래를 보라).

mapping-file, jar-file, class

class 요소는 당신이 매핑하게 될 전체 수식된 클래스명을 지정한다. 현재, 당신은 당신이 JBoss 어플리케이션 서버 내에서 실행하고 있지 않을 경우 당신이 매핑시켰던 각각의 클래스에 대해 class XML 요소를 지정해야 한다. 명세서는 클래스 이름들, 매핑된 파일들에 대한 자동적인 검출을 허용하지만, 이것은 아직 구현되어 있지 않다. mapping-file과 jar-file은 아직 어느 것도 지원되지 않는다.

properties

properties 요소는 벤더에 특정한 프로퍼티들을 지정하는데 사용된다. 이곳이 당신이 당신의 Hibernate 지정적인 프로퍼티들을 정의하게 될 장소이다. 이곳은 또한 마찬가지로 당신이 JDBC 연결 정보를 지정해야할 장소이다.

EJB3 명세서는 EntityManagerFactoryEntityManager에 접근하기 위한 하나의 부트스트랩 절차를 정의하고 있다. 부트스트랩 클래스는 javax.persistence.Persistence이다. 예를 들면.

EntityManagerFactory emf = Persistence.createEntityManagerFactory("manager1");
//or
Map configOverrides = new HashMap();
configuration.put("hibernate.hbm2ddl.auto", "create-drop");
EntityManagerFactory programmaticEmf =
    Persistence.createEntityManagerFactory("manager1", configOverrides);

첫 번째 버전은 하나의 공백의 map을 가진 두 번째 버전과 동등하다. map 버전은 당신의 persistence.xml 파일들 내에 정의된 임의의 프로퍼티들에 대해 우선하게 될 오버라이드들의 세트이다. Persistence.createEntityManagerFactory()이 호출될 때, 영속 구현은 ClassLoader.getResource("META-INF/persistence.xml") 메소드를 사용하여 임의의 META-INF/persistence.xml 파일들을 당신의 classpath에서 검색할 것이다. 리소스들에 대한 이 목록으로부터, 그것은 당신이 명령 라인에 지정한 이름이 persistence.xml 파일 내에 정의된 것과 일치하는 하나의 엔티티 관리자를 찾으려고 시도할 것이다.

Hibernate 시스템 레벨의 설정들과는 별개로, Hibernate에서 이용 가능한 모든 프로퍼티들이 persistence.xml 파일의 properties 요소 내에 설정될 수 있거나 당신이 createEntityManagerFactory>()에 전달하는 map 내의 하나의 오버라이드로서 설정될 수 있다. 전체 목록에 대한 것은 Hibernate 참조 문서를 참조하길 바란다. 하지만 EJB3 공급자에서만 이용 가능한 한 쌍의 프로퍼티들이 존재한다.

표 2.1. Hibernate 엔티티 관리자에 특정에 프로퍼티들

프로퍼티 이름설명
hibernate.ejb.classcache.<classname>클래스에 대한 클래스 캐시 방도[쉼표 캐시 영역]. 디폴트는 no cache이고, fully.qualified.classname에 대한 디폴트 영역 캐시(예를 들면. hibernate.ejb.classcache.com.acme.Cat read-write or hibernate.ejb.classcache.com.acme.Cat read-write, MyRegion).
hibernate.ejb.collectioncache.<collectionrole>클래스에 대한 콜렉션 캐시 방도[쉼표 캐시 영역]. 디폴트는 no cache이고, fully.qualified.classname.role에 대한 디폴트 영역 캐시(예를 들면. hibernate.ejb.classcache.com.acme.Cat read-write or hibernate.ejb.classcache.com.acme.Cat read-write, MyRegion).
hibernate.ejb.cfgfileHibernate를 구성하는데 사용할 XML 구성 파일(예를 들면. /hibernate.cfg.xml)

당신은 동일한 구성에서 xml <class> 선언과 hibernate.ejb.cfgfile 사용법을 혼합할 수 없음을 노트하라. 한 개의 선언 방도를 선택하라. 만일 당신이 <class>를 선택할 경우, Hibernate는 hibernate.ejb.cfgfile파일을 사용하고자 시도할 것이다. 만일 당신이 <class>를 사용하고자 원할 경우, hibernate.ejb.cfgfile이 무시될 것이다. 당신은 당신의 클래스들을 명시적으로 선언해야 하고, 한 개의 .par 아카이브 내에서 클래스들에 대한 자동 검출은 스탠드얼론 방도에서는 구현되지 않음을 기억하라.

다음은 하나의 J2SE 환경에서의 전형적인 구성이다

<entity-manager>
   <name>manager1</name>
   <class>org.hibernate.ejb.test.Cat</class>
   <class>org.hibernate.ejb.test.Distributor</class>
   <class>org.hibernate.ejb.test.Item</class>
   <properties>
       <property name="hibernate.dialect" value="org.hibernate.dialect.HSQLDialect"/>
       <property name="hibernate.connection.driver_class" value="org.hsqldb.jdbcDriver"/>
       <property name="hibernate.connection.username" value="sa"/>
       <property name="hibernate.connection.password" value=""/>
       <property name="hibernate.connection.url" value="jdbc:hsqldb:."/>
       <property name="hibernate.max_fetch_depth" value="3"/>
       
       <!-- cache configuration -->
       <property name="hibernate.ejb.classcache.org.hibernate.ejb.test.Item" value="read-write"/>
       <property name="hibernate.ejb.collectioncache.org.hibernate.ejb.test.Item.distributors" value="read-write, RegionName"/>

       <!-- alternatively to <class> and <property> declarations, you can use a regular hibernate.cfg.xml file -->
       <!-- property name="hibernate.ejb.cfgfile" value="/org/hibernate/ejb/test/hibernate.cfg.xml"/ -->
   </properties>
</entity-manager>

2.3. J2SE 환경에서 하나의 EntityManagerFactory와 하나의 EntityManager 획득하기

하나의 엔티티 관리자 팩토리는 하나의 불변의 구성 소유자로서 간주되어야 하여, 그것은 단일 데이터소스를 가리키기 위해 그리고 엔티티들에 대한 하나의 정의된 집합을 매핑하기 위해 정의된다. 이것은 EntityManager들을 생성시키고 관리하기 위한 진입점이다. Persistence 클래스는 하나의 엔티티 관리자 팩토리를 생성시키기 위한 부트스트랩 클래스이다.

// Use persistence.xml configuration
EntityManagerFactory emf = Peristence.createEntityManagerFactory("manager1")
EntityManager em = emf.createEntityManager(); // Retrieve a transactional-scoped entity manager
// Work with the EM
em.close();
...
emf.close(); //close at application end

하나의 엔티티 관리자 팩토리는 일반적으로 어플리케이션 초기화 시에 생성되고 어플리케이션 종료 시에 닫혀진다. 그것의 생성은 값비싼 과정들이다. Hibernate에 익숙해져 있는 사용자들의 경우, 하나의 엔티티 관리자 팩토리는 한의 세션 팩토리와 매우 흡사하다. 실제로, 하나의 엔티티 관리자 팩토리는 하나의 세션 팩토리의 상단에 있는 하나의 포장 꾸러미(wrapper)이다.

두 가지 종류의 엔티티 관리자들이 존재한다. 트랜잭션-영역의 엔티티 관리자(디폴트)는 각각의 트랜잭션에 대해 하나의 영속 컨텍스트를 생성시키고 파괴시킨다: 달리 말해, 관리되는 엔티티들은 일단 그 트랜잭션이 종료되면 detach(분리)된다. 확장된 엔티티 관리자는 그 엔티티 관리자의 생명주기 동안에 동일한 영속 컨텍스트를 유지한다: 달리말해, 엔티티들은 여전히 두 개의 트랜잭션들 사이에서 관리된다. emf.createEntityManager()는 하나의 트랜잭션-영역의 엔티티 관리자를 생성시키고 emf.createEntityManager(PersistenceContextType.EXTENDED)는 하나의 확장된 엔티티 관리자를 생성시킨다. 당신은 하나의 Hibernate 세션의 상단에 있는 하나의 작은 포장 꾸러미(wrapper)로서 하나의 엔티티 관리자를 볼 수 있다.