「Spring」 Hibernate と連携してみる ( Spring 3 系 + Hibernate 3 系 )
Spring ( 3.2.12 ) と Hibernate ( 3.6.10 ) を連携してみたので、メモしておきます。
使うパッケージは org.springframework.orm.hibernate3 になるみたいです。
・org.springframework.orm.hibernate3 (Spring Framework 3.2.13.RELEASE API)
http://docs.spring.io/spring/docs/3.2.13.RELEASE/javadoc-api/org/springframework/orm/hibernate3/package-summary.html
ドキュメントは以下あたりに。
・15. Object Relational Mapping (ORM) Data Access
http://docs.spring.io/spring/docs/3.2.13.RELEASE/spring-framework-reference/html/orm.html#orm-hibernate
1. DAO クラスを作成する
■ PersonDAO.java
package com.example.hibernate; import java.util.List; public interface PersonDAO { public List<Person> getAllPerson(); public void addPerson(Person p); }
■ PersonDAOImpl.java
package com.example.hibernate; import java.util.List; import org.hibernate.Session; import org.hibernate.SessionFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; @Component public class PersonDAOImpl implements PersonDAO { @Autowired private SessionFactory sessionFactory; public void setSessionFactory(SessionFactory sessionFactory) { this.sessionFactory = sessionFactory; } @Override public List<Person> getAllPerson() { List<Person> persons = sessionFactory.getCurrentSession().createCriteria(Person.class).list(); return persons; } @Override public void addPerson(Person p) { sessionFactory.getCurrentSession().persist(p); } protected Session openSession() { return sessionFactory.openSession(); } }
@Autowired で SessionFactory オブジェクトされるようにしています。
設定は後述しますが、LocalSessionFactoryBean を Bean 定義ファイルに記述することで Hibernate の SessionFactory を生成してくれるみたいです。
・LocalSessionFactoryBean (Spring Framework 3.2.13.RELEASE API)
http://docs.spring.io/spring/docs/3.2.13.RELEASE/javadoc-api/org/springframework/orm/hibernate3/LocalSessionFactoryBean.html
2. サービスクラスを作成する
■ PersonService.java
package com.example.hibernate; import java.util.List; public interface PersonService { public List<Person> getAllPerson(); public void addPerson(Person p); }
■ PersonServiceImpl.java
package com.example.hibernate; import java.util.List; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; import org.springframework.transaction.annotation.Transactional; @Component public class PersonServiceImpl implements PersonService { @Autowired PersonDAO dao; @Override @Transactional(readOnly = true) public List<Person> getAllPerson() { return dao.getAllPerson(); } @Override @Transactional public void addPerson(Person p) { dao.addPerson(p); } }
3. Bean 定義ファイルを作成する
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context" xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.2.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.2.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.2.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.2.xsd"> <context:property-placeholder location="classpath:jdbc.properties"/> <bean id="myDataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close"> <property name="driverClassName" value="${driver}" /> <property name="url" value="${url}" /> <property name="username" value="${username}" /> <property name="password" value="${password}" /> </bean> <bean id="mySessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean"> <property name="dataSource" ref="myDataSource"/> <property name="mappingResources"> <list> <value>com/example/hibernate/Person.hbm.xml</value> </list> </property> <property name="hibernateProperties"> <props> <prop key="hibernate.dialect">org.hibernate.dialect.PostgreSQLDialect</prop> <prop key="hibernate.show_sql">true</prop> <prop key="hibernate.hbm2ddl.auto">update</prop> </props> </property> </bean> <bean id="transactionManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager"> <property name="sessionFactory" ref="mySessionFactory"/> </bean> <tx:annotation-driven transaction-manager="transactionManager"/> <context:annotation-config /> <context:component-scan base-package="com.example.hibernate" /> </beans>
Hibernate との連携の固有の設定は、LocalSessionFactoryBean、HibernateTransactionManager あたりですかね。
ドキュメントではトランザクションインタセプタの設定を Bean 定義ファイルで行なっていますが、面倒なので上記ではアノテーション使ってやるようにしています。
4. Main クラスを作成する
■ Main.java
package com.example.hibernate; import java.util.List; import org.springframework.context.support.ClassPathXmlApplicationContext; import org.springframework.stereotype.Component; public class Main { public static void main(String[] args) { new Main().test(); } public void test() { try (ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("hibernate.xml")) { PersonService ps = context.getBean(PersonService.class); Person p = new Person(); p.setId(3); p.setName("oro"); ps.addPerson(p); List<Person> persons = ps.getAllPerson(); for (Person person : persons) { System.out.println(person.getId() + ":" + person.getName()); } } } }
作成するものは、上記で以上です。
log4j の設定ファイルで、HibernateTransactionManager のデバッグログを有効にしてやると ( *1 )、以下のようなログが出力されるはずです。ひとまずちゃんと動いてそうかな。
2015-03-24 00:59:43,350 INFO HibernateTransactionManager - Using DataSource [org.apache.commons.dbcp.BasicDataSource@66328ec4] of Hibernate SessionFactory for HibernateTransactionManager 2015-03-24 00:59:43,383 DEBUG HibernateTransactionManager - Creating new transaction with name [com.example.hibernate.PersonServiceImpl.addPerson]: PROPAGATION_REQUIRED,ISOLATION_DEFAULT; '' 2015-03-24 00:59:43,404 DEBUG HibernateTransactionManager - Opened new Session [org.hibernate.impl.SessionImpl@656ebb9] for Hibernate transaction 2015-03-24 00:59:43,405 DEBUG HibernateTransactionManager - Preparing JDBC Connection of Hibernate Session [org.hibernate.impl.SessionImpl@656ebb9] 2015-03-24 00:59:43,415 DEBUG HibernateTransactionManager - Exposing Hibernate transaction as JDBC transaction [jdbc:postgresql://127.0.0.1:5432/testdb, UserName=*****, PostgreSQL Native Driver] 2015-03-24 00:59:43,424 DEBUG HibernateTransactionManager - Initiating transaction commit 2015-03-24 00:59:43,424 DEBUG HibernateTransactionManager - Committing Hibernate transaction on Session [org.hibernate.impl.SessionImpl@656ebb9] Hibernate: insert into T1 (name, id) values (?, ?) 2015-03-24 00:59:43,459 DEBUG HibernateTransactionManager - Closing Hibernate Session [org.hibernate.impl.SessionImpl@656ebb9] after transaction 2015-03-24 00:59:43,460 DEBUG HibernateTransactionManager - Creating new transaction with name [com.example.hibernate.PersonServiceImpl.getAllPerson]: PROPAGATION_REQUIRED,ISOLATION_DEFAULT,readOnly; '' 2015-03-24 00:59:43,460 DEBUG HibernateTransactionManager - Opened new Session [org.hibernate.impl.SessionImpl@3872dcd8] for Hibernate transaction 2015-03-24 00:59:43,460 DEBUG HibernateTransactionManager - Preparing JDBC Connection of Hibernate Session [org.hibernate.impl.SessionImpl@3872dcd8] 2015-03-24 00:59:43,461 DEBUG HibernateTransactionManager - Exposing Hibernate transaction as JDBC transaction [jdbc:postgresql://127.0.0.1:5432/testdb, UserName=*****, PostgreSQL Native Driver] Hibernate: select this_.id as id0_0_, this_.name as name0_0_ from T1 this_ 2015-03-24 00:59:43,471 DEBUG HibernateTransactionManager - Initiating transaction commit 2015-03-24 00:59:43,471 DEBUG HibernateTransactionManager - Committing Hibernate transaction on Session [org.hibernate.impl.SessionImpl@3872dcd8] 2015-03-24 00:59:43,472 DEBUG HibernateTransactionManager - Closing Hibernate Session [org.hibernate.impl.SessionImpl@3872dcd8] after transaction 1:hoge 2:uga 3:oro
( *1 )
log4j.appender.stderr=org.apache.log4j.ConsoleAppender log4j.appender.stderr.Target=System.err log4j.appender.stderr.layout=org.apache.log4j.PatternLayout log4j.appender.stderr.layout.ConversionPattern=%d %5p %c{1} - %m%n log4j.logger.org.springframework.orm.hibernate3.HibernateTransactionManager=DEBUG,stderr
だいぶかけ足でしたが、以上です。
[ 環境情報 ]
Windows 7 SP1
Java SE 7 Update 51
Spring Framework 3.2.13
Hibernate 3.6.10.Final
PostgreSQL 9.0.4
PostgreSQL JDBC Driver 9.0-801