3장. 설정

오픈소스 비즈니스 컨설팅
둘러보기로 가기 검색하러 가기

Hibernate는 많은 다른 환경에서 동작하도록 만들어졌기 때문에 많은 설정 파라미터들이 있습니다. 다행히, 대부분들은 의미있는 기본값들을 가지며, Hibernate는 다양한 선택사항들을 보여주는 etc/ 에 예제 hibernate.properties 파일이 포함되서 배포됩니다. 예제 파일을 클래스패스에 넣고 수정하면 됩니다.


3.1 프로그램으로 설정

org.hibernate.cfg.Configuration 인스턴스는 어플리케이션의 Java 타입을 SQL 데이터베이스로의 전체 맵핑을 대표합니다. Configuration은 (수정할 수 없는) SessionFactory를 만드는데에 사용됩니다. 맵핑은 다양한 XML 맵핑 파일로부터 컴파일 됩니다.

직접 이를 인스턴스화하고 XML 맵핑 문서를 지정함으로써 Configuration 인스턴스를 얻을 수 있습니다. 만일 맵핑 파일이 클래스패스에 위치하고 있다면, 다음과 같이 addResource()를 사용합니다.

Configuration cfg = new Configuration()
   .addResource("Item.hbm.xml")
   .addResource("Bid.hbm.xml");

다른(때로 더 좋은) 방법은 맵핑된 클래스를 지정하고, 다음과 같이 Hibernate가 맵핑 문서를 찾게하는 것입니다.

Configuration cfg = new Configuration()
   .addClass(org.hibernate.auction.Item.class)
   .addClass(org.hibernate.auction.Bid.class);

다음에 Hibernate는 클래스패스에서 /org/hibernate/auction/Item.hbm.xml과 /org/hibernate/auction/Bid.hbm.xml인 맵핑 파일을 검색합니다. 이러한 방법은 손으로 만드는 파일명을 없애줍니다.

Configuration 또한 다음과 같이 설정 속성을 지정하게 해줍니다.

Configuration cfg = new Configuration()
   .addClass(org.hibernate.auction.Item.class)
   .addClass(org.hibernate.auction.Bid.class)
   .setProperty("hibernate.dialect", "org.hibernate.dialect.MySQLInnoDBDialect")
   .setProperty("hibernate.connection.datasource", "java:comp/env/jdbc/test")
   .setProperty("hibernate.order_updates", "true");

위의 방법만이 Hibernate에 대한 설정 속성을 세팅하는 것이 아닙니다. 다음과 같이 다양한 방법들이 있습니다.

* java.util.Properties의 인스턴스를 Configuration.setProperties() 로 넘김.
* 클래스패스의 루트 디렉토리에 hibernate.properties 를 위치시킴.
* java -Dproperty=value 를 사용해서 System 속성 세팅.
* hibernate.cfg.xml에 <property> 요소 포함. (이후 설명)

hibernate.properties는 빨리 시작하기를 원한다면 가장 쉬운 방법입니다.

Configuration 은 기동시의 객체로, 일단 SessionFactory 가 만들어지면 없어집니다.

3.2 SessioinFactory 가져오기

모든 맵핑들이 Configuration 에 의해서 파싱되었을때 어플리케이션은 Session 인스턴스들에 대한 factory를 가져와야 합니다. 이 factory는 다음과 같이 모든 어플리케이션 쓰레드에서 공유됩니다.

SessionFactory sessions = cfg.buildSessionFactory();

Hibernate는 어플리케이션이 하나 이상의 SessionFactory를 초기화 가능토록 합니다. 이는 하나 이상의 DB를 사용하는 경우에 사용됩니다.


3.3 JDBC 연결

보통 SessionFactory가 JDBC 연결을 생성하고 풀링하기를 원합니다. 만일 이러한 방법을 사용하려면, Session을 여는 것은 다음과 같이 단순합니다.

Session session = sessions.openSession(); // open a new Session

DB 접근에 필요한 어떤 것을 수행하자마자, JDBC 연결은 해당 풀에서 가져오게 됩니다.

이와같이 작동하게 하기 위해서 Hibernate에 JDBC 연결 속성을 넘겨줄 필요가 있습니다. 모든 Hibernate 속성명과 의미는 org.hibernate.cfg.Environment 클래스에 정의되어 있습니다. 지금부터 JDBC 연결 설정에 대해 가장 중요한 세팅을 설명하겠습니다.

Hibernate는 다음과 같이 세팅한 경우 java.sql.DriverManager를 사용해서 연결을 가지고 옵니다 (혹은 풀링합니다).

표 3.1 Hibernate JDBC 속성

속성명목적
hibernate.connection.driver_classJDBC 드라이버 클래스
hibernate.connection.urlJDBC URL
hibernate.connection.usernameDB 아이디
hibernate.connection.passwordDB 패스워드
hibernate.connection.pool_size풀링된 연결의 최대 갯수

Hibernate의 자체 연결 풀링 알고리즘은 거의 초보적인 수준입니다. 처음 시작하는 데에 도움을 주려고 만든 것이며 제품 시스템 사용이나 성능 테스트 용으로 만든 것은 아닙니다. 최적의 성능과 안정성을 위해서는 다른 풀을 사용해야 합니다. 단지 hibernate.connection.pool_size 속성을 연결 풀의 특정 세팅으로 바꾸면 됩니다. 이는 Hibernate의 내부 풀을 설정하지 않게 합니다. 예를 들어, C3P0 를 사용하는 것입니다.

C3P0는 Hibernate와 같이 lib 디렉토리에 같이 배포되는 오픈 소스 JDBC 연결 풀입니다. Hibernate는 hibernate.c3p0.* 속성을 세팅하면 연결 풀링에 대해서 C3P0ConnectionProvider를 사용합니다. 만일 Proxool을 사용하고자 한다면 포함된 hibernate.properties를 참조하고 더 자세한 정보는 Hibernate 웹 사이트를 참고하세요.

다음은 C3P0에 대한 예제 hibernate.properties 입니다.

hibernate.connection.driver_class = org.postgresql.Driver
hibernate.connection.url = jdbc:postgresql://localhost/mydatabase
hibernate.connection.username = myuser
hibernate.connection.password = secret
hibernate.c3p0.min_size=5
hibernate.c3p0.max_size=20
hibernate.c3p0.timeout=1800
hibernate.c3p0.max_statements=50
hibernate.dialect = org.hibernate.dialect.PostgreSQLDialect

어플리케이션 서버 내부에서 사용시 거의 대부분이 어플리케이션 서버의 JNDI 에 등록된 Datasource로부터 연결을 얻어오도록 Hibernate를 설정해야 합니다. 최소한 다음 속서 중에 하나는 세팅되어야 합니다.

표 3.2 Hibernate 데이터소스 속성

Propery namePurpose
hibernate.connection.datasource데이터소스 JNDI명
hibernate.jndi.urlJNDI provider의 URL (선택)
hibernate.jndi.classJNDI InitialContextFactory의 클래스 (선택)
hibernate.connection.usernameDB 아이디 (선택)
hibernate.connection.passwordDB 패스워드 (선택)

다음은 JNDI 데이터소스가 제공된 어플리케이션 서버에 대한 예제 hibernate.properties 파일입니다.

hibernate.connection.datasource = java:/comp/env/jdbc/test
hibernate.transaction.factory_class = \
   org.hibernate.transaction.JTATransactionFactory
hibernate.transaction.manager_lookup_class = \
   org.hibernate.transaction.JBossTransactionManagerLookup
hibernate.dialect = org.hibernate.dialect.PostgreSQLDialect

JNDI 데이터소스로부터 얻어온 JDBC 연결은 자동으로 어플리케이션 서버의 컨테이너 관리 트랜잭션(container-managed transaction)에 참여합니다.

임의의 연결 속성은 속성명에 "hibernate.connnection" 를 앞에 붙여서 부여하게 됩니다. 예를 들어, hibernate.connection.charSet 을 사용해서 charSet을 지정할 수 있습니다.

org.hibernate.connection.ConnectionProvider 인터페이스를 구현해서 JDBC 연결을 얻는 자체 플러그인 방식을 정의할 수도 있습니다. hibernate.connection.provider_class를 세팅하여 구현된 것을 선택할 수도 있습니다.


3.4 선택적인 설정 속성들

실행시에 Hibernate의 행위를 통제하는 수많은 다른 속성들이 있습니다. 모두는 선택사항이며 기본적인 값을 가집니다.

주의 : 이러한 속성들 중에 어떤 것들을 "시스템 차원"인 것도 있습니다. 시스템 차원의 속성들은 java -Dproperty=value 이나 hibernate.properties를 통해서만 세팅될 수 있습니다. 위에서 언급한 다른 방식으로는 세팅될 수 없을 것입니다.


표 3.3 Hibernate 설정 속성들

속성명목적
hibernate.dialect 특정 관계형 DB에 대해 최적화된 SQL 생성을 가능하게 하는 Hibernate Dialect의 클래스명.
예. full.classname.of.Dialect
hibernate.show_sql 콘솔이 모든 SQL 구문을 출력. 디버깅을 위한 org.hibernate.SQL 로그 카테고리의 다른 방법임.
. true | false
hibernate.format_sql 로그와 콘솔에 SQL을 형식에 맞춰서 출력.
. true | false
hibernate.default_schema 생성된 SQL에 주어진 스키마/테이블스페이스와 같이 지정되지 않은 테이블명에 이름을 지정함.
. SCHEMA_NAME
hibernate.default_catalog 생성된 SQL에 주어진 카탈로그와 같이 지정되지 않은 테이블에 이름을 지정함.
. CATALOG_NAME
hibernate.session_factory_name SessionFactory가 생성된 후에 JNDI에 이 이름으로 자동으로 세팅됨.
. jndi/composite/name
hibernate.max_fetch_depth 하나로 종료되는 관계(일대일, 다대일)에 대해서 외부 조인의 fetch 트리에 대한 최대 "깊이" 세팅. 0값은 기본으로 외부 조인 fetching을 비활성화 시킴.
. 0과 3 사이 값을 추천
hibernate.default_batch_fetch_size 연관에 대해서 Hibernate의 batch fetching의 기본 크기 세팅.
. 4, 8, 16 값을 추천
hibernate.default_entity_mode 해당 SessionFactory로부터 열려진 모든 세션에 대해 엔티티 표현에 대한 기본 모드 세팅.
dynamic-map, dom4j, pojo
hibernate.order_updates 수정될 항목의 PK 값에 의해서 SQL 수정 순서를 강제로 지정함. 매우 동이성이 높은 시스템에서 트랜잭션 데드락이 발생될 확률이 낮음.
. true | false
hibernate.generate_statistics true이면 성능 튜닝에 사용될 수 있는 통계를 수집함.
. true | false
hibernate.use_identifer_rollback true이면 생성된 식별자 속성들이 객체가 삭제되었을 때 기본 값으로 재세팅됨.
. true | false
hibernate.use_sql_comments true이면, 디버깅을 쉽게 하기 위해 SQL 내에 주석을 생성하며, 기본값은 false임.
. true | false


표 3.4 Hibernate JDBC와 연결 속성

속성명목적
hibernate.jdbc.fetch_size 0 이 아닌 값은 JDBC의 fetch 크기를 결정함. (Statement.setFetchSize() 호출)
hibernate.jdbc.batch_size 0이 아닌 값은 Hibernate에 의해서 JDBC2 배치 수정에서 사용 가능함.
예. 5에서 30 사이의 값 추천
hibernate.jdbc.batch_versioned_data JDBC 드라이버가 executeBatch() 에서 정확한 행의 count를 반환하려면 이 속성을 true 로 세팅함. (이 설정을 세팅하는 것이 통상 안전함.) Hibernate는 자동으로 버전 데이터에 대한 배치 DML을 사용함. 기본값을 false임.
예. true | false
hibernate.jdbc.factory_class 사용자가 작성한 Batcher 지정. 대부분의 어플리케이션은 이 설정 속성을 필요로 하지 않음.
예. classname.of.Batcher
hibernate.jdbc.use_scrollable_resultset Hibernate에서 JDBC2의 scrollable 결과셋을 사용하게 함. 이 설정은 사용자에게 제공된 JDBC 연결을 사용할 때 필요하며, 그렇지 않을 경우 Hibernate는 연결 메타 정보를 사용함.
예. true | false
hibernate.jdbc.use_streams_for_binary JDBC의 바이너리 혹은 직렬화된 타입을 읽고/쓰는 경우에 스티림을 사용함. (시스템 레벨 속성)
예. true | false
hibernate.jdbc.use_get_generated_keys INSERT 후 내부적으로 생성된 key 값을 조회하기 위한 JDBC3 PreparedStatement.getGeneratedKeys() 사용을 가능하게 함. JDBC3 이상의 드라이버와 JRE 1.4 이상을 필요로 하며, 드라이버가 Hibernate 식별자 생성에 문제가 발생시 false로 세팅함. 기본적으로 연결 메타 정보를 사용해서 드라이버의 기능을 결정함.
예. true|false
hibernate.connection.provider_class Hibernate에 JDBC 연결을 제공하는 사용자가 작성한 ConnectionProvider의 클래스명.
예. classname.of.ConnectionProvider
hibernate.connection.isolation JDBC 트랜잭션 isolation 수준을 세팅. 의미있는 값에 대해서는 java.sql.Connection을 점검해야 하지만, 대부분의 DB는 모든 isolation 수준을 지원하지 않음을 유의해야 함.
예. 1, 2, 4, 8
hibernate.connection.autocommit JDBC의 풀링된 연결에 대한 autocommit 설정을 가능하게 함. (추천하지 않음)
예. true | false
hibernate.connection.release_mode Hibernate가 JDBC 연결을 release해야 하는 시점을 지정함. 기본적으로 JDBC 연결은 세션이 명시적으로 닫히거나 끊어질 때까지 유지됨. 어플리케이션 서버 JTA 데이터소스에 대해서 모든 JDBC 호출 후에 직접적으로 연결을 release하기 위해서 after_statement 를 사용해야 함. JTA가 아닌 연결에 대해서 after_transaction을 사용해서 각 트랜잭션의 끝에 연결을 release 시키는 의미가 종종 있음. auto는 JTA와 CMT 트랜잭션 전략에 대해서 after_statement와 JDBC를 위해서 after_transaction를 선택함.

예. auto (기본값) | on_close | after_transaction | after_statement

이 설정은 SessionFactory.openSession으로부터 반환받은 Session에만 영향을 미침에 유의. SessionFactory.getCurrentSession를 통해 얻은 Session에 대해서 사용을 위해 설정된 CurrentSessionContext 구현체는 해당 세션들에 대한 연결 release 모드를 통제함. [2.5 영역 세션] 참조
hibernate.connection.<propertyName> JDBC 속성 propertyName를 DriverManager.getConnection()에 전달함.
hibernate.jndi.<propertyName> 속성 propertyName 를 JNDI InitialContextFactory에 전달함.


표 3.5 Hibernate 캐싱 속성

속성명목적
hibernate.cache.provider_class 사용자가 작성한 CacheProvider의 클래스명
예. classname.of.CacheProvider
hibernate.cache.use_minimal_puts 좀 더 자주 읽는 비용에 대해서 입력을 최소화시키기 위해 2차 수준의 캐싱 오퍼레이션의 최적화. 이 세팅은 클러스터링된 캐싱에서 매우 유용하며, Hibernate3에서 기본적으로 클러스터링된 캐싱 구현체에 대해 설정이 가능함.
예. true|false
hibernate.cache.use_query_cache 쿼리 캐싱에 대해서 설정하며, 개별 쿼리들은 캐싱되도록 해야 함.
예. true|false
hibernate.cache.use_second_level_cache 2차 수준의 캐싱을 완전히 비활성하는데 사용될 수 있으며, <cache> 맵핑을 지정하는 클래스에 대해서 기본적으로 세팅될 수 있음.
예. true|false
hibernate.cache.query_cache_factory 사용자가 작성한 QueryCache에 대한 클래스명. 기본적으로 내장된 StandardQueryCache 값 사용.
예. classname.of.QueryCache
hibernate.cache.region_prefix 2차 수준 캐싱 지역명에 사용시 접두어
예. prefix
hibernate.cache.use_structured_entries 좀 더 사용자에게 친숙한 형태로 2차 수준 캐싱에 데이터를 저장함.
예. true|false

표 3.6. Hibernate 트랜잭션 속성

속성명목적
hibernate.transaction.factory_class Hibernate 트랜잭션 API와 같이 사용되는 TransactionFactory의 클래스 명 (기본으로 JDBCTransactionFactory).
예. classname.of.TransactionFactory
jta.UserTransaction 어플리케이션 서버로부터 JTA UserTransaction 을 얻기 위해 JTATransactionFactory에 의해 사용되는 JNDI 명.
예. jndi/composite/name
hibernate.transaction.manager_lookup_class JVM 상의 캐싱이 설정되거나 JTA 환경의 hilo generator가 사용될 때 필요로 하는 TransactionManagerLookup의 클래스명.
예. classname.of.TransactionManagerLookup
hibernate.transaction.flush_before_completion 세팅된 경우, 세션은 트랜잭션이 완료되기 전에 자동으로 flush됨. 내장되고 자동 세션 영역 관리를 선호함. 2.5 영역 세션 참조.
예. true | false
hibernate.transaction.auto_close_session 세팅된 경우, 세션은 트랜잭션 종료 후에 자동으로 닫힘. 내장되고 자동 세션 영역 관리를 선호함. 2.5 영역 세션 참조.
예. true | false

표 3.7 기타 속성

속성명목적
hibernate.current_session_context_class "현재" 세션의 영역에 대한 (사용자 제공) 방법을 제공함. 내장 방법에 대한 더 자세한 정보는 2.5 영역 세션 참고.
예. jta | thread | managed | custom.Class
hibernate.query.factory_class HQL 파서 구현체 선택.
예. org.hibernate.hql.ast.ASTQueryTranslatorFactory 혹은 org.hibernate.hql.classic.ClassicQueryTranslatorFactory
hibernate.query.substitutions SQL 토큰에 대한 Hibernate 쿼리에서 토큰으로부터의 맵핑 (토큰은 함수 혹은 이름이 될 수 있음.)
예. hqlLiteral=SQL_LITERAL, hqlFunction=SQLFUNC
hibernate.hbm2ddl.auto SessionFactory가 생성될 때 스키마 DDL를 DB에 자동으로 검증하거나 export 함. create-drop 인 경우, DB 스키마는 SessionFactory가 명시적으로 닫힐 때 drop 됨.
예. validate | update | create | create-drop
hibernate.cglib.use_reflection_optimizer 실시간 리플렉션 대신 CGLIB 사용을 세팅함. (시스템 수준의 속성) 리플렉션은 문제 해결시 종종 유용하며, Hibernate는 이 설정을 세팅하지 않더라도 항상 CGLIB을 사용함에 주의. hibernate.cfg.xml 에 이 설정을 세팅할 수 없음.
예. true | false


3.4.1 SQL Dialect

hibernate.dialect 속성에 대해서 항상 해당 DB에 맞는 org.hibernate.dialect.Dialect 하위 클래스를 설정해야 합니다. dialect를 설정하면, Hibernate는 위에 표시한 다른 속성들의 몇가지는 의미있는 기본값을 사용하며, 이는 수동으로 설정하는 시간을 줄여줍니다.

표 3.8 Hibernate SQL Dialect (hibernate.dialect)

RDBMSDialect
DB2org.hibernate.dialect.DB2Dialect
DB2 AS/400org.hibernate.dialect.DB2400Dialect
DB2 OS390org.hibernate.dialect.DB2390Dialect
PostgreSQLorg.hibernate.dialect.PostgreSQLDialect
MySQLorg.hibernate.dialect.MySQLDialect
MySQL with InnoDBorg.hibernate.dialect.MySQLInnoDBDialect
MySQL with MyISAMorg.hibernate.dialect.MySQLMyISAMDialect
Oracle (any version)org.hibernate.dialect.OracleDialect
Oracle 9i/10gorg.hibernate.dialect.Oracle9Dialect
Sybaseorg.hibernate.dialect.SybaseDialect
Sybase Anywhereorg.hibernate.dialect.SybaseAnywhereDialect
Microsoft SQL Serverorg.hibernate.dialect.SQLServerDialect
SAP DBorg.hibernate.dialect.SAPDBDialect
Informixorg.hibernate.dialect.InformixDialect
HypersonicSQLorg.hibernate.dialect.HSQLDialect
Ingresorg.hibernate.dialect.IngresDialect
Progressorg.hibernate.dialect.ProgressDialect
Mckoi SQLorg.hibernate.dialect.MckoiDialect
Interbaseorg.hibernate.dialect.InterbaseDialect
Pointbaseorg.hibernate.dialect.PointbaseDialect
FrontBaseorg.hibernate.dialect.FrontbaseDialect
Firebirdorg.hibernate.dialect.FirebirdDialect


3.4.2 Outer Join Fetching

만일 DB가 ANSI를 지원하면 Oracle 이나 Sybase 형태의 outer join인 outer join fetching이 DB로부터의 연결 횟수를 줄임으로써 성능을 향상시키기도 합니다. (DB 자체에 대해 수행되는 더 많은 작업 비용에 비해서) Outer join fetching은 단일 SQL SELECT 에 조회되는 다대일, 다대다, 일대일 관계에 의해 연결된 객체의 전체 그래프를 허용합니다.

Outer join fetching은 hibernate.max_fetch_depth 속성값을 0으로 세팅함으로써 전체적으로(globally) 비활성화시킬 수 있습니다. 1 이상의 값에 대한 세팅은 fetch="join"로 관계를 맺은 일대일과 다대일에 대한 outer join fetching을 허용합니다.

자세한 사항은 19.1 Fetching 전략을 참고하세요.


3.4.4 바이너리 스트림

오라클은 JDBC 드라이버를 통해 전달될 수 있는 byte 배열의 수를 한정합니다. 만일 대용량의 바이너리(binary)나 직렬화(serializable) 유형을 사용하고자 한다면 hibernate.jdbc.use_streams_for_binary 를 활성화해야 합니다. 이는 시스템 수준 세팅입니다.


3.4.4 이차 수준과 쿼리 캐싱

hibernate.cache에 의해서 사전에 고정된 속성은 Hibernate와 같이 프로세스 혹은 클러스터 범위의 이차 수준 캐싱 시스템을 사용하도록 합니다. 자세한 사항은 19.2 이차수준 캐싱을 참조하세요.


3.4.5 쿼리 언어 대체

hibernate.query.substitutions을 사용해서 새로운 Hibernate 쿼리 토큰을 정의할 수 있습니다. 예를 들어,

hibernate.query.substitutions true=1, false=0

는 생성된 SQL에서 정수값으로 true와 false 값을 해석하게끔 하는 토큰을 정하게 됩니다.

hibernate.query.substitutions toLowercase=LOWER

는 SQL LOWER 함수를 재명명하는 것입니다.


3.4.6 Hibernate 통계

만일 hibernate.generate_statistics를 설정하면, Hibernate는 SessionFactory.getStatistics()를 통해 운영되는 시스템을 튜닝할 때 유용한 많은 매트릭스를 제공합니다. Hibernate는 JMX를 통해서 이러한 통계를 보여주도록 설정할 수도 있습니다. 더 자세한 정보는 org.hibernate.stats에 있는 인터페이스에 대한 Javadoc를 읽으세요.


3.5 로깅

Hibernate는 다양한 시스템 이벤트를 로깅하기 위해서 Simple Logging Facade for Java http://www.slf4j.org/ (SLF4J)를 사용합니다. SLF4J는 바인딩 하도록 선택된 것에 따라 몇가지 로깅 프레임워크(NOP, Simple, log4j version 1.2, JDK 1.4 logging, JCL 혹은 logback)에 로깅을 보낼 수 있습니다. 로깅을 적절하게 셋업하기 위해서 Log4J의 경우 바인딩할 slf4j-log4j12.jar에 대한 jar 파일과 같이 클래스패스에 slf4j-api.jar가 필요합니다. 자세한 사항은 SLF4J 문서 http://www.slf4j.org/manual.html 를 참고하세요. Log4J를 사용하기 위해 클래스패스에 log4j.properties을 위치시키는 것이 필요하며, 예제 설정 파일은 src/ 디렉토리에 Hibernate와 같이 배포됩니다.

Hibernate의 로그 메세지에 대해서 익숙해지기를 강력히 권고합니다. 많은 작업들이 읽기 가능한 형태로 Hibernate 로그에 가능한 한 자세하게 나타납니다. 이는 문제를 해결하는데 있어서 기본적인 장치입니다. 가장 관심이 있는 로그 카테고리는 다음과 같은 것들이 있습니다.

표 3.9 Hibernate 로그 카테고리

카테고리기능
org.hibernate.SQL 모든 SQL DML 문을 남김.
org.hibernate.type 모든 JDBC 파라미터를 남김
org.hibernate.tool.hbm2ddl 모든 SQL DDL 문을 남김.
org.hibernate.pretty flush 시에 세션과 관련된 모든 엔티티(최대 20개)에 대한 문을 남김.
org.hibernate.cache 모든 2차 수준 캐싱 내역을 남김.
org.hibernate.transaction 내역과 관련된 트랜잭션을 남김.
org.hibernate.jdbc 모든 JDBC 자원 획득을 남김.
org.hibernate.hql.ast.AST 쿼리 파싱 동안의 HQL과 SQL AST를 남김.
org.hibernate.secure 모든 JAAS 권한 요청을 남김.
org.hibernate 모든 것을 남김. (많은 정보가 나타나지만, 문제 해결시 매우 유용함.)


Hibernate를 사용해서 개발하는 경우, org.hibernate.SQL 카테고리에 대해서 debug로 거의 항상 활성화하거나, hibernate.show_sql 속성을 활성화합니다.


3.6 NamingStrategy 구현

org.hibernate.cfg.NamingStrategy 인터페이스는 DB 객체와 스키마 요소에 대해서 "표준화된 명명"을 지정하는 것을 가능하게 합니다.

자바 식별자로부터 DB 식별자를 자동으로 생성하거나 맵핑 파일에 있는 "논리적인" 컬럼과 테이블명을 "물리적인" 테이블과 컬럼명으로 만드는 규칙을 제공할 수 있습니다. 이러한 기능은 반복적인 작업을 없애면서(예를 들어, TBL_ 접두사) 맵핑 문서에 대한 많은 작업을 줄이는데 도움이 됩니다. Hiberante에 의해 사용되는 기본적인 방법은 매우 최소화되어 있습니다.

맵핑을 수행하기 전에 Configuration.setNamingStrategy()을 호출해서 다음과 같이 다른 방법을 지정할 수 있습니다.

SessionFactory sf = new Configuration()
   .setNamingStrategy(ImprovedNamingStrategy.INSTANCE)
   .addFile("Item.hbm.xml")
   .addFile("Bid.hbm.xml")
   .buildSessionFactory();

org.hibernate.cfg.ImprovedNamingStrategy는 어플리케이션에 대해 유용한 시작 지점이 될 수 있는 내장 strategy입니다.


3.7 XML 설정 파일

설정에 대한 다른 방법은 hibernate.cfg.xml 라고 하는 파일에 전체 설정을 지정하는 것입니다. 이 파일은 hibernate.properties 파일에 대한 대체로 사용될 수 있으며, 두가지가 모두 존재하면, 속성이 오버라이딩됩니다.

XML 설정 파일은 기본적으로 CLASSPATH의 루트에 위치됩니다. 다음은 그 예입니다.

<?xml version='1.0' encoding='utf-8'?>
 <!DOCTYPE hibernate-configuration PUBLIC
    "-//Hibernate/Hibernate Configuration DTD//EN"
    "http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
 
 <hibernate-configuration>
 
    <!-- a SessionFactory instance listed as /jndi/name -->
    <session-factory
        name="java:hibernate/SessionFactory">
 
        <!-- properties -->
        <property name="connection.datasource">java:/comp/env/jdbc/MyDB</property>
        <property name="dialect">org.hibernate.dialect.MySQLDialect</property>
        <property name="show_sql">false</property>
        <property name="transaction.factory_class">
            org.hibernate.transaction.JTATransactionFactory
        </property>
        <property name="jta.UserTransaction">java:comp/UserTransaction</property>
 
        <!-- mapping files -->
        <mapping resource="org/hibernate/auction/Item.hbm.xml"/>
        <mapping resource="org/hibernate/auction/Bid.hbm.xml"/>
 
        <!-- cache settings -->
        <class-cache class="org.hibernate.auction.Item" usage="read-write"/>
        <class-cache class="org.hibernate.auction.Bid" usage="read-only"/>
        <collection-cache collection="org.hibernate.auction.Item.bids" usage="read-write"/>
 
    </session-factory>

 </hibernate-configuration>

보는 바와 같이 이러한 방법의 장점은 설정에 대한 맵핑 파일명을 가시화할 수 있다는 것입니다. hibernate.cfg.xml는 또한 Hibernate 캐싱을 튜닝해야 한다면 매우 편리합니다. hibernate.properties를 사용할지 hibernate.cfg.xml를 사용할지는 선택이지만, XML 문법을 사용한다는 이점을 제외하고 두가지 모두 동일합니다.

XML 설정을 사용하면 Hibernate의 시작은 다음과 같이 매우 간단해집니다.

SessionFactory sf = new Configuration().configure().buildSessionFactory();

다음과 같이 다른 XML 설정 파일을 선택할 수 있습니다.

SessionFactory sf = new Configuration()
   .configure("catdb.cfg.xml")
   .buildSessionFactory();


3.8 J2EE 어플리케이션 서버 통합

Hibernate는 J2EE 인프라에 대해 다음과 같은 통합 지점을 가지고 있습니다.

  • 컨테이너 관리 데이터 소스: Hibernate는 컨테이너가 관리하고 JNDI를 통해 제공되는 JDBC 연결을 사용할 수 있습니다. 보통, JTA 호환이 가능한 TransactionManager 와 ResourceManager 는 특히, 여러 데이터 소스를 통해 분산 트랜잭션 처리를 하는 트랜잭션 관리(CMT)를 담당합니다. 물론 프로그램적으로 트랜잭션 영역을 선언할 수도 있으며(BMT) 혹은 코드가 이동가능하게 하기 위해 이를 위한 선택적인 Hibernate Transaction API를 사용하기 원할 수도 있습니다.
  • 자동 JNDI 바인딩 : Hibernate는 기동 후 SessionFactory를 JNDI에 바인딩 할 수 있습니다.
  • JTA 세션 바인딩 : Hibernate Session은 JTA 트랜잭션 영역에 자동으로 위치할 수 있습니다. 단순히 JNDI로부터 SessionFactory를 검색하고 현재 Session을 가지고 오면 됩니다. Hibernate가 JTA 트랜잭션이 완료될 때 Session읠 flushing과 closing을 담당하게 하면 됩니다. 트랜잭션 선언은 선언적(CMT)이거나 프로그램적(BMT/UserTransaction)입니다.
  • JMX 배포 : 만일 JMX 가능한 어플리케이션 서버가 있다면 (예를 들어, JBoss AS), Hibernate를 관리 MBean 으로 배포하는 것이 가능합니다. 이는 Configuration으로부터 SessionFactory를 만들기 위한 한줄의 초기 코드를 없애줍니다. 컨테이너는 HiberanteService를 기동할 것이며, 이상적으로 서비스 의존성을 관리할 것입니다. (데이터소스는 Hibernate가 시작 전에 가용해야 한다 등)

3.8.1. 트랜잭션 방법 설정

Hibernate 세션 API는 해당 아키텍처에 있는 어떠한 트랜잭션 선언 시스템과도 독립적입니다. 연결 풀을 통해 Hibernate에서 JDBC로 직접 사용하려고 한다면, JDBC API를 호출해서 트랜잭션의 시작과 종료를 수행할 수 있습니다. 만일 J2EE 어플리케이션 서버에서 실행한다면 BMT를 사용하고 JTA API를 호출하거나 필요시 UserTransaction을 호출하기 원할 것입니다.

이러한 두가지 환경 간에 코드를 이식 가능하게 유지하려면 선택적인 Hibernate 트랜잭션 API를 추천합니다. 이는 내부적인 시스템은 감싸고 숨겨줍니다. Hibernate 설정 속성인 hibernate.transaction.factory_class 값을 세팅해서 트랜잭션 인스턴스에 대한 factory 클래스를 지정해야 합니다.

다음은 세가지 표준 (내장) 설정입니다.

org.hibernate.transaction.JDBCTransactionFactory
DB (JDBC) 트랜잭션으로 위임 (기본값)

org.hibernate.transaction.JTATransactionFactory
기존 트랜잭션이 해당 컨텍스트(예를 들면, EJB 세션 빈 메소드)에 포함되어 
있으면 CMT에게 위임하고, 그렇지 않으면 새로운 트랜잭션을 시작하고 BMT를 사용

org.hibernate.transaction.CMTTransactionFactory
컨테이너 관리 JTA 트랜잭션으로 위임.

또한 자신의 트랜잭션 방법 정의가 가능합니다. (예를 들어, CORBA 트랜잭션 서비스)

Hibernate의 어떤 기능(예를 들어, 이차 수준의 캐싱, JTA를 포함한 영역 세션 등)은 관리 환경의 JTA TransactionManager로의 접근을 필요로 합니다. 어플리케이션 서버에서 Hibernate가 TransactionManager에 대한 참조를 어떻게 얻어와야 하는지를 지정해주어야 하는데, 이는 J2EE가 다음과 같이 단일 메커니즘을 표준화하지 않기 때문입니다.

표 3.10 JTA TransactionManager

Transaction Factory어플리케이션 서버
org.hibernate.transaction.JBossTransactionManagerLookup JBoss
org.hibernate.transaction.WeblogicTransactionManagerLookup Weblogic
org.hibernate.transaction.WebSphereTransactionManagerLookup WebSphere
org.hibernate.transaction.WebSphereExtendedJTATransactionLookup WebSphere 6
org.hibernate.transaction.OrionTransactionManagerLookup Orion
org.hibernate.transaction.ResinTransactionManagerLookup Resin
org.hibernate.transaction.JOTMTransactionManagerLookup JOTM
org.hibernate.transaction.JOnASTransactionManagerLookup JOnAS
org.hibernate.transaction.JRun4TransactionManagerLookup JRun4
org.hibernate.transaction.BESTransactionManagerLookup Borland ES


3.8.2 JNDI-영역 SessionFactory

JNDI 영역 Hibernate SessionFactory는 factory 검색과 새로운 Session을 생성하는 것을 단순화시킬 수 있습니다. 이는 JNDI 영역 Datasource와 관련이 없으며, 모두 동일한 레지트리를 단순하게 사용함에 유의하세요! JNDI namesapce에 영역의 SessionFactory를 가지려고 한다면, hibernate.session_factory_name 속성을 사용해서 이름(예를 들어,java:hibernate/SessionFactory) 을 지정합니다. (이는 Tomcat과 같은 읽기만 가능한 JNDI 기본 구현체를 가지는 환경에서 특히 유용합니다.) JNDI에 SessionFactory를 엮을때 Hibernate는 초기 영역을 인스턴스화하는 hibernate.jndi.url, hibernate.jndi.class의 값을 사용합니다. 만일 지정되어 있지 않다면, 기본 InitialContext가 사용됩니다. Hibernate는 cfg.buildSessionFactory()를 호출한 다음에 자동으로 SessionFactory를 JNDI에 위치시킵니다. 이는 HibernateService를 가지는 JMX 배포를 사용하지 않는다면(이후 설명) 어플리케이션에 기동 코드 (혹은 유틸리티 클래스)에 이 호출을 최소한 위치시켜야 됨을 의미합니다. JNDI SessionFactory를 사용한다면, EJB나 다른 클래스는 JNDI 검색을 사용해서 SessionFactory를 얻어올 수 있습니다. 관리 환경에서 SessionFactory를 JNDI로 bind 하고 그렇지 않다면 static singleton을 사용하기를 추천합니다. 이러한 세부사항으로부터 어플리케이션을 보호하려면 HibernateUtil.getSessionFactory()과 같은 헬퍼 클래스에 SessionFactory에 대한 실질적인 검색 코드를 감추기를 권합니다. 그러한 클래스는 또한 Hibernate를 기동하는 편리한 방법임을 유의하세요. (1장 참고)


3.8.3 JTA를 포함하는 context 관리 현재 Session

Session과 트랜잭션을 다루는 가장 쉬운 방법은 Hibernate의 자동화된 "현재" 세션 관리입니다. "현재 세션"에 대한 설명을 참고하세요. "jta" 세션 영역을 사용해서 현재 JTA 트랜잭션과 관련이 있는 Hibernate Session이 없다면 sessionFactory.getCurrentSession()을 처음 호출했을 때 JTA 트랜잭션과 관련되어서 기동할 수 있습니다.