Spring+HibernateEntityManager(とりあえずSpring編)

前回は、HibernateEntityManager を使ったベタなサンプルでした。今回は、とりあえず Spring Framework を使ってみるという程度に拡張します。

拡張点

  • 機能実行部を Serivce として抜き出し。
  • EntityManagerFactory を Serivce に DI することにして、EntityManagerFactory の生成に関して実装クラスへの依存を排除。
  • persistence.xml の位置を自由に変更するために、LocalContainerEntityManagerFactoryBean を使用。
  • persistence.xml の位置を、META-INF/persistence.xml から、persistence.xml に変更。

変更ソース

sample.Service

機能の実行を行うサービスクラス。

package sample;

import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.EntityTransaction;

public class Service {
    
    /**
     * DI される EntityManagerFactory
     */
    private EntityManagerFactory emf; // $Proxy6 クラス
    
    /**
     * @param emf
     */
    public void setEmf(EntityManagerFactory emf) {
        this.emf = emf;
    }
    
    public void persistA() {
        
        EntityManager em = emf.createEntityManager();
        // em は $Proxy7 クラス
        
        EntityTransaction tx = em.getTransaction();
        // tx は org.hibernate.ejb.TransactionImpl クラス
        
        tx.begin();
        // DB : SET autocommit=0
        
        em.persist(new A());
        // DB : insert into A values ( )
        
        tx.commit();
        // DB : commit
        // DB : SET autocommit=1
    }
    
}
beans.xml

ApplicationContextの設定ファイル。

<?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"
  xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-2.5.xsd"
>
  <!-- persistence.xml の位置指定や LTW 等の設定も可能な FactoryBean -->
  <bean id="emf" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
    <property name="persistenceXmlLocation" value="persistence.xml" />
  </bean>
  
  <!-- Service -->
  <bean id="service" class="sample.Service">
    <property name="emf" ref="emf" />
  </bean>
  
</beans>
sample.SampleMain

機能の実行を、ApplicationContextから取得したService経由で行うように変更。

package sample;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class SampleMain {
    
    // A を新規作成し、DB に保存
    public static void main(String[] args) throws Exception {
        
        // ApplicationContext の取得
        ApplicationContext ctx = new ClassPathXmlApplicationContext("beans.xml");
        
        // Service の取得
        Service service = (Service) ctx.getBean("service");
        
        // A を新規作成し、DB に保存
        service.persistA();
        
    }
}

参考

サンプル