Trasis Inc.

渋谷拠点のシステム開発会社

Hibernate で一時的に二次キャッシュを利用せずにエンティティを追加する

概要

JPA(EntityManager) + Hibernate + Ehcache(二次キャッシュ) + Seasar2 の組み合わせで利用しているとき、二次キャッシュを利用せずにエンティティを生成 (insert) する方法について解説します。

想定するケース

  • Ehcache を使い、マルチキャストにより LAN 内で二次キャッシュを共有している。
  • あるエンティティは @Cache アノテーションにより、二次キャッシュを利用している。
  • 大量にそのエンティティを追加するときは二次キャッシュを利用したくない。

この場合、最も簡単かつ推奨する方法は

  • 二次キャッシュを利用しない設定で構築した Web サーバまたはコマンドライン・プログラムを用意し、そこで処理を実行する。

ですが、なんらかの理由で二次キャッシュを利用した web サーバ上で処理を実行しなければならない場合、以下の手順で実現できます。

設定手順

META-INF/persistence.xml に記述を追加

META-INF/persistence.xml で既存の persistenceUnit タグをコピーし、二次キャッシュを利用しない設定を行います。

<persistence-unit name="db1nocache_persistenceUnit" transaction-type="JTA">
<provider>org.hibernate.ejb.HibernatePersistence</provider>
<jta-data-source>jdbc/dataSource</jta-data-source>
<class>sample.entity.Shop</class>
<exclude-unlisted-classes>true</exclude-unlisted-classes>
<properties>
<property name="hibernate.jndi.class" value="org.seasar.extension.j2ee.JndiContextFactory"/>
<property name="hibernate.transaction.manager_lookup_class"
value="org.seasar.hibernate.jpa.transaction.SingletonTransactionManagerProxyLookup"/>
<property name="hibernate.cache.use_query_cache"	value="false" />
<property name="hibernate.cache.use_second_level_cache"	value="false" />
</properties>
</persistence-unit>

具体的には、以下の修正を行います。

  • persistence-unit タグの name 属性を db1nocache_persistenceUnit のような名前に変更してください。
  • 利用するエンティティを明示的に class タグで宣言してください。中で別のエンティティを参照している場合、それらもすべて宣言する必要があります。
  • hibernate.cache.use_query_cache を false に設定。
  • hibernate.cache.use_second_level_cache を false に設定。

jpa_nocache.dicon を作成

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE components PUBLIC "-//SEASAR//DTD S2Container 2.4//EN"
"http://www.seasar.org/dtd/components24.dtd">
<components>
<include path="s2hibernate-jpa.dicon"/>
<component name="db1nocache_persistenceUnitProvider" class="org.seasar.framework.jpa.impl.ContainerPersistenceUnitProvider">
<property name="unitName">"db1nocache_persistenceUnit"</property>
<property name="properties">
#{
"hibernate.dialect" : "org.hibernate.dialect.PostgreSQLDialect",
"hibernate.show_sql" : "false",
"hibernate.hbm2ddl.auto" : "none"
}
</property>
</component>
<component name="db1nocache_entityManagerFactory" class="javax.persistence.EntityManagerFactory">
db1nocache_persistenceUnitProvider.entityManagerFactory
</component>
<component name="db1nocache_entityManager" class="org.seasar.framework.jpa.impl.TxScopedEntityManagerProxy"/>
</components>

jpa.dicon から jpa_nocache.dicon を呼び出す

jpa.dicon の components タグの後ろに、次の記述を追加します。

<include path="jpa_nocache.dicon"/>

利用手順

Service クラスの中で次のように利用します。

public class TestService {
@Binding(value = "db1nocache_entityManager")
private EntityManager nocacheEntityManager;
@RequiredTx
public void exec() throws IOException {
Shop shop = new Shop();
// shop エンティティの設定
...
nocacheEntityManager.persist(genre);
}
}