Hibernate은 실행 속성을 포함하고 있는 hibernate.cfg.xml (또는
hibernate.properties)을 기반으로 하여 동작하도록 구성되어 있다. 본 페이지에서는
hibernate.cfg.xml 파일의 주요 구성 요소와 속성 정의 방법에 대해 살펴보기로 한다. 먼저,
hibernate.cfg.xml 파일은 가장 상위에 <hibernate-configuration>
태그를 포함하고 있으며 <hibernate-configuration> 태그 내에
<security>와 <session-factory>를 포함할 수 있다.
<session-factory>는 Hibernate SessionFactory가 DB 정보와
Hibernate Mapping XML 정보를 기반으로 Session을 생성하여 전달하는데 필요한 정보를
정의하기 위한 태그이다. <session-factory> 내에는 다양한 속성 정의가 가능하나 본
페이지에서는 그 중 일부 속성에 대해서만 다루기로 한다. Hibernate Configuration에 대한
자세한 내용은
Cache 속성 정의
| Name
|
Description
|
| hibernate.cache.provider_class |
Cache 기능을 구현하고 있는 구현체의 클래스명을 정의하기 위한 속성 |
| hibernate.cache.use_second_level_cache |
2nd Level Cache를 적용할지 여부를 정의하기 위한 속성 (true|false) |
| hibernate.cache.use_query_cache |
Hibernate Query를 Caching할지 여부를 정의하기 위한 속성 (true|false) |
다음은 위에서 언급한 속성들을 포함하고 있는
hibernate.cfg.xml
파일의 일부이다. 2nd Level Cache를 적용하고, Cache Provider로 EhCacheProvider를 사용한 예이다.
<session-factory>
...
<property name="hibernate.cache.provider_class">org.hibernate.cache.EhCacheProvider</property>
<property name="hibernate.cache.use_second_level_cache">true</property>
...
<session-factory>
Logging 속성 정의
| Name
|
Description
|
| hibernate.show_sql |
Hibernate을 통해 생성된 SQL을 콘솔에 남길 것인지 여부를 정의하는 속성 (true|false) |
| hibernate.format_sql |
hibernate.show_sql=true인 경우 해당 SQL문의 포맷을 정돈하여 콘솔에 남길 것인지
여부를 정의하는 속성 (true|false) |
| hibernate.use_sql_comments |
Hibernate을 통해 생성된 SQL을 콘솔에 남길 때 Comments도 같이 남길 것인지
여부를 정의하는 속성 (true|false) |
위에서 언급한 hibernate.show_sql, hibernate.format_sql 속성을 정의하였을 경우 Hibernate를 통해 생성된 SQL문은 다음과 같은 형태로
콘솔에 남게 된다.
Hibernate:
insert
into
PUBLIC.COUNTRY
(COUNTRY_ID, COUNTRY_NAME, COUNTRY_CODE)
values
(?, ?, ?)
Hibernate 기본 Logging은 생성된 SQL 문을 확인할 때에는 유용하나 전달된 인자값을 확인할 수가 없어서 개발시 불편할
것이다.
Hibernate에서는 기본 SQL Logging 외에도 Jakarta commons-logging API를 사용하여 로그를 처리하고 있어서,
logging을 위한 속성 파일을 정의하고 다음과 같은 로그 카테고리 목록을 활용하면 개발시 로그를 통해 좀 더 유용한 정보를
얻어낼 수 있을 것이다.
| 카테고리 |
설명 |
| org.hibernate.SQL |
실행되는 모든 DML 쿼리 Logging |
| org.hibernate.type |
모든 JDBC 인자 Logging |
| org.hibernate.tool.hbm2ddl |
실행되는 모든 DDL 쿼리 Logging |
| org.hibernate.pretty |
Flush 수행시 세션에 저장된 모든 개체(최대 20개)의 상태를 Logging
|
| org.hibernate.cache |
2nd Level Cache 수행 내역을 Logging |
| org.hibernate.transaction |
트랜잭션 수행 내역을 Logging |
| org.hibernate.jdbc |
모든 JDBC 자원 요청을 Logging |
| org.hibernate.hql.ast.AST |
쿼리를 파싱하는 동안 HQL과 SQL AST를 Logging |
| org.hibernate.secure |
모든 JAAS 인증 요청을 Logging |
다음은 hibernate.cfg.xml 파일 내의 hibernate.show_sql 설정과 무관하게, log4j.xml 파일 내에
org.hibernate.SQL, org.hibernate.type Logger의 로그 레벨을 DEBUG로 정의하였을 경우
HibernateBasicCRUDTest.java
실행으로 인해
콘솔에 남은 SQL문의 일부이다.
1. log4j.xml
<log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/">
...
<logger name="org.hibernate.SQL">
<level value="DEBUG" />
</logger>
<logger name="org.hibernate.type">
<level value="DEBUG" />
</logger>
...
</log4j:configuration>
2. Console - Hibernate Log
DEBUG: org.hibernate.SQL -
insert
into
PUBLIC.COUNTRY
(COUNTRY_ID, COUNTRY_NAME, COUNTRY_CODE)
values
(?, ?, ?)
DEBUG: org.hibernate.type.StringType - binding 'KR' to parameter: 1
DEBUG: org.hibernate.type.StringType - binding 'Korea' to parameter: 2
DEBUG: org.hibernate.type.StringType - binding 'COUNTRY-0001' to parameter: 3
위에서 언급한 2가지 방법 외에도
Log4jdbc(http://log4jdbc.sourceforge.net/)
라는 오픈소스를 활용하면
다음과 같이 SQL문에 입력 인자가 대체된 형태의 SQL문을 로그를 통해 확인할 수도 있다.
Log4jdbc를 활용한 Query Logging 방법에 대해서 자세히 알고 싶은 경우
여기
를
참조하도록 한다.
DEBUG: jdbc.sqlonly - org.hibernate.jdbc.BatchingBatcher.doExecuteBatch(BatchingBatcher.java:48)
1. batching 1 statements:
1: insert into PUBLIC.COUNTRY (COUNTRY_ID, COUNTRY_NAME, COUNTRY_CODE) values ('KR', 'Korea',
'COUNTRY-0001')
기타 속성 정의
| Name
|
Description
|
| hibernate.hbm2ddl.auto |
Hibernate Mapping XML File (*.hbm.xml)을 기반으로
DDL을 자동으로 검증,생성 또는 수정할지 여부를 정의하기 위한 속성
(validate|update|create|create-drop) |
| hibernate.jdbc.batch_size |
Hibernate는 일반적으로 실행해야 할 SQL들에 대해 일괄적으로 batch 처리를 수행하는데
이 때 batch로 처리할 SQL의 개수를 정의하기 위한 속성 |
hibernate.hbm2ddl.auto 속성을 정의한 경우 별도 DDL 없이도 정의된 Hibernate Mapping XML 파일을
기반으로 해당 DB에 관련된 테이블을 생성, 수정, 검증 등을 수행하게 된다.
다음은 hibernate.hbm2ddl.auto=create로 정의한
hibernate.cfg.xml
과
이를 기반으로 해당 DB에 관련 테이블을 생성하면서 실행된 DDL의 일부이다.
1. hibernate.cfg.xml
<session-factory>
...
<property name="hbm2ddl.auto">create</property>
...
<session-factory>
2. Console - Hibernate Log
...
DEBUG: jdbc.sqlonly - org.hibernate.tool.hbm2ddl.SchemaExport.execute(SchemaExport.java:308)
1. {WARNING: Statement used to run SQL} create table MOVIE_CATEGORY
(CATEGORY_ID varchar(9) not null, MOVIE_ID varchar(255) not null, primary key (MOVIE_ID, CATEGORY_ID))
DEBUG: jdbc.sqlonly - org.hibernate.tool.hbm2ddl.SchemaExport.execute(SchemaExport.java:308)
1. {WARNING: Statement used to run SQL} create table PUBLIC.CATEGORY
(CATEGORY_ID varchar(9) not null, CATEGORY_NAME varchar(50) not null, CATEGORY_DESC varchar(100),
primary key (CATEGORY_ID))
DEBUG: jdbc.sqlonly - org.hibernate.tool.hbm2ddl.SchemaExport.execute(SchemaExport.java:308)
1. {WARNING: Statement used to run SQL} create table PUBLIC.COUNTRY
(COUNTRY_CODE varchar(12) not null, COUNTRY_ID varchar(2) not null, COUNTRY_NAME varchar(50) not null,
primary key (COUNTRY_CODE))
DEBUG: jdbc.sqlonly - org.hibernate.tool.hbm2ddl.SchemaExport.execute(SchemaExport.java:308)
1. {WARNING: Statement used to run SQL} create table PUBLIC.MOVIE
(MOVIE_ID varchar(255) not null, COUNTRY_CODE varchar(12), TITLE varchar(100) not null,
DIRECTOR varchar(10) not null, RELEASE_DATE date, primary key (MOVIE_ID))
...
다음은 hibernate.jdbc.batch_size=10으로 정의한
hibernate.cfg.xml
과
이를 기반으로 하는
HibernateMultiDataSaveTest
의
실행 결과의 일부이다. HibernateMultiDataSaveTest 코드의 session.flush() 부분을 breakpoint로 지정하고,
DEBUG 모드로 실행시켜 보면서 batch 처리가 제대로 이루어지는지 확인해 보자.
DEBUG: jdbc.sqlonly - org.hibernate.jdbc.BatchingBatcher.doExecuteBatch(BatchingBatcher.java:48)
1. batching 10 statements:
1: insert into PUBLIC.COUNTRY (COUNTRY_ID, COUNTRY_NAME, COUNTRY_CODE) values ('KR0', 'Korea0',
'COUNTRY-0000')
2: insert into PUBLIC.COUNTRY (COUNTRY_ID, COUNTRY_NAME, COUNTRY_CODE) values ('KR1', 'Korea1',
'COUNTRY-0001')
3: insert into PUBLIC.COUNTRY (COUNTRY_ID, COUNTRY_NAME, COUNTRY_CODE) values ('KR2', 'Korea2',
'COUNTRY-0002')
4: insert into PUBLIC.COUNTRY (COUNTRY_ID, COUNTRY_NAME, COUNTRY_CODE) values ('KR3', 'Korea3',
'COUNTRY-0003')
5: insert into PUBLIC.COUNTRY (COUNTRY_ID, COUNTRY_NAME, COUNTRY_CODE) values ('KR4', 'Korea4',
'COUNTRY-0004')
6: insert into PUBLIC.COUNTRY (COUNTRY_ID, COUNTRY_NAME, COUNTRY_CODE) values ('KR5', 'Korea5',
'COUNTRY-0005')
7: insert into PUBLIC.COUNTRY (COUNTRY_ID, COUNTRY_NAME, COUNTRY_CODE) values ('KR6', 'Korea6',
'COUNTRY-0006')
8: insert into PUBLIC.COUNTRY (COUNTRY_ID, COUNTRY_NAME, COUNTRY_CODE) values ('KR7', 'Korea7',
'COUNTRY-0007')
9: insert into PUBLIC.COUNTRY (COUNTRY_ID, COUNTRY_NAME, COUNTRY_CODE) values ('KR8', 'Korea8',
'COUNTRY-0008')
10: insert into PUBLIC.COUNTRY (COUNTRY_ID, COUNTRY_NAME, COUNTRY_CODE) values ('KR9', 'Korea9',
'COUNTRY-0009')
매핑 파일 정의
Hibernate를 통해 관리되어야 할 Mapping XML File 목록을 정의하기 위한 속성이며, 다음과 같이 정의할 수 있다.
<session-factory>
...
<mapping resource="anyframe/sample/model/bidirection/Category.hbm.xml"/>
<mapping resource="anyframe/sample/model/bidirection/Country.hbm.xml"/>
<mapping resource="anyframe/sample/model/bidirection/Movie.hbm.xml"/>
...
<session-factory>