hibernate와 C3P0 연동 설정 예
최근 프로젝트에서 hibernate로 MySQL를 사용하였다. 그런데 가끔 다음과 같은 예외가 발생한다. 

com.mysql.jdbc.exceptions.jdbc4.MySQLNonTransientConnectionException: Communications link failure during commit(). Transaction resolution unknown.

com.mysql.jdbc.exceptions.jdbc4.CommunicationsException: The last packet successfully received from the server was 52,194,478 milliseconds ago. The last packet sent successfully to the server was 52,194,478 milliseconds ago. is longer than the server configured value of 'wait_timeout'. You should consider either expiring and/or testing connection validity before use in your application, increasing the server configured values for client
timeouts, or using the Connector/J connection property 'autoReconnect=true' to avoid this problem.

컨넥션을 사용한 지 오래되서 MySQL 서버쪽에서 연결을 귾어 버린 상황 같다. 위 메시지 대로 connection URL에 autoRecoonect=true를 포함시켰는데도 문제는 해결되지 않았다.


그래서 컨넥션을 주기적으로 체크하기 위하여 C3P0를 사용하기로 하였다.

그런데 이 과정에서의 설정 속성 관련하여 얀간의 혼동이 있었고, 제대로 동작하는 설정을 공유하고자 한다.


사실 Hibernate와 C3P0를 동시에 사용할 필요는 없다. Hibernate 내에 자체 pool이 지원되고 있고, autoReconnect=true와 같은 컨넥션 체크 방법이 적용된다면 말이다. 아마도 적용 어디선가 잘못된것 같은데, 하여간에 Hibernate와 C3P0를 같이 사용하게 되었다. 이런 필요가 별로 없는 것을 증명하 듯, 이에 관련된 문서가 많지 않다.

다음은 maven의 dependency 설정이다.

<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-c3p0</artifactId>
<version>4.0.1.Final</version>
</dependency>



그리고 다음은 hibernate의 설정이다.

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-configuration PUBLIC "-//Hibernate/Hibernate Configuration DTD 3.0//EN" "http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
<session-factory>

<property name="hibernate.connection.driver_class">net.sf.log4jdbc.DriverSpy</property>
<property name="hibernate.connection.url">jdbc:log4jdbc:mysql://host:3306/dbname?characterEncoding=utf8</property>
<property name="hibernate.connection.username">user</property>
<property name="hibernate.connection.password">password</property>
<property name="hibernate.dialect">org.hibernate.dialect.MySQLDialect</property>
<property name="current_session_context_class">thread</property>
<property name="hibernate.show_sql">false</property>
<property name="hibernate.format_sql">true</property>
<property name="hbm2ddl.auto">validate</property>
<property name="hibernate.c3p0.validate">true</property>
<property name="hibernate.connection.provider_class">org.hibernate.service.jdbc.connections.internal.C3P0ConnectionProvider</property>
<property name="hibernate.c3p0.minPoolSize">5</property>
<property name="hibernate.c3p0.maxPoolSize">50</property>
<property name="hibernate.c3p0.timeout">0</property>
<property name="hibernate.c3p0.maxStatements">500</property>
<property name="hibernate.c3p0.preferredTestQuery">SELECT 1;</property>
<property name="hibernate.c3p0.idleConnectionTestPeriod">3000</property>

</session-factory>
</hibernate-configuration>


특이한 것은 설정 속성의 이름이 '_' 사용하는 것과 소대문자 구별의 Camel 표기법이 혼용되어 있다. provider_class는 '_'를 사용하였고, 나머지는 Camel 표기법이다. 이것은 Hibernate에서 C3P0를 가져다 쓰면서 발생한 상황이다. C3P0에서는 Camel 표기법을 사용하였고, Hibernate는 '_'를 사용하였는데, 위 설정 중 provider_class를 제외한 속성은 C3P0의 것을 가져온 것이고, provider_class는 Hibernate에서 자체 정의한 것이다. 그래서 설정 속성 이름 표기가 혼용되어 있다.

문서(http://www.mchange.com/projects/c3p0/index.html#hibernate-specific)를 보면 Hibernate에서 7개의 C3P0 설정 속성 이름을 재정의 하였다고 하는데, 그냥 위와 같이 Camel 방법을 사용하여도 설정이 적용되는 것을 확인하였다.

다시 정리하면 
  • 속성 이름은 C3P0에서 사용하는 속성 이름을 그대로 사용하며,
  • 속성 이름 앞에 "hibernate.c3p0."를 붙인다

C3P0의 설정 속성 리스트는 http://www.mchange.com/projects/c3p0/index.html#configuration_properties에서 확인할 수 있다.

그리고 적용된 C3P0의 설정은 Log4j의 다음 설정으로 로그에서 확인할 수 있다.

<logger name="com.mchange.v2.c3p0" additivity="false">
<level value="INFO" />
<appender-ref ref="ASYNC" />
</logger>








by 어플로잇 | 2013/05/08 11:09 | java tip | 트랙백 | 덧글(0)
트랙백 주소 : http://aploit.egloos.com/tb/5742484
☞ 내 이글루에 이 글과 관련된 글 쓰기 (트랙백 보내기) [도움말]

:         :

:

비공개 덧글

< 이전페이지 다음페이지 >