#chiroito ’s blog

Java を中心とした趣味の技術について

Coherence+S2JDBC CacheLoader,CacheStore編

JPAHibernateとの連携はOracle社の公式ドキュメントに記載されていますがS2JDBCに関する情報は一切無かったため作成してみました。
ソースが多いため文章は短めです。

目的

CoherenceS2JDBCでデータの読み書き連携を行います。

環境

Java 6.0
Seasar 2.4.43
Coherence 3.6.1
Eclipse Java EE IDE for Web Developers.Helios Service Release 1

データベース側の準備

まずはS2JDBCのクラスを作成するためのテーブル定義とサンプルソースを実行するためのサンプルデータを投入します。
CREATE TABLE "SEASAR"."EMPLOYEE"
(
"COMPANY_ID" VARCHAR2(20 BYTE) NOT NULL ENABLE,
"EMPLOYE_ID" NUMBER NOT NULL ENABLE,
"NAME" VARCHAR2(20 BYTE),
"AGE" NUMBER,
CONSTRAINT "EMPLOYEE_PK" PRIMARY KEY ("COMPANY_ID", "EMPLOYE_ID") USING INDEX
);
INSERT INTO "SEASAR"."EMPLOYEE" (COMPANY_ID, EMPLOYE_ID, NAME, AGE) VALUES ('OR', '1', '佐藤', '18');

CacheLoaderのサンプル

package com.chirokings.coherence.s2jdbc;

import java.util.Collection;
import java.util.List;
import java.util.Map;
import javax.persistence.NonUniqueResultException;
import org.seasar.extension.jdbc.EntityMeta;
import org.seasar.extension.jdbc.EntityMetaFactory;
import org.seasar.extension.jdbc.JdbcManager;
import org.seasar.extension.jdbc.PropertyMeta;
import org.seasar.extension.jdbc.exception.NonEntityRuntimeException;
import org.seasar.framework.container.SingletonS2Container;
import org.seasar.framework.util.tiger.ReflectionUtil;
import com.tangosol.net.cache.CacheLoader;
import com.tangosol.util.Base;

public class S2jdbcCacheLoader extends Base implements CacheLoader {

/** 対象となるエンティティのメタデータ */
private EntityMeta entityMeta;

/**
* コンストラクタ
* @param entityName 対象となるエンティティ名
* @throws NonEntityRuntimeException
* @throws NullPointerException
* @throws ClassNotFoundException
*/
public S2jdbcCacheLoader(String entityName) throws NonEntityRuntimeException, NullPointerException, ClassNotFoundException{
EntityMetaFactory emf = SingletonS2Container.getComponent(EntityMetaFactory.class);
this.entityMeta = emf.getEntityMeta(Class.forName(entityName));
}

@Override
public Object load(Object arg0) {
//コンテナからJDBCマネージャの取得
JdbcManager jdbc = SingletonS2Container.getComponent("jdbcManager");

//主キーのメタデータを取得
List pks = this.entityMeta.getIdPropertyMetaList();

//主キー条件を作成
Object[] where = new Object[pks.size()];
int j=0;
for( PropertyMeta i : pks ){
where[j++] = ReflectionUtil.getValue(i.getField(), arg0);
}

//DBからデータの取得
Object ret = null;
try{
ret = jdbc.from(this.entityMeta.getEntityClass()).id(where).getSingleResult();
} catch (NonUniqueResultException e) {
}

return ret;
}

@SuppressWarnings({ "rawtypes" })
@Override
public Map loadAll(Collection arg0) {
throw new UnsupportedOperationException();
}
}

CacheStoreのサンプル

このクラスはNameCacheのput,getを行うと呼ばれるクラスです。
package com.chirokings.coherence.s2jdbc;

import java.util.Collection;
import java.util.Map;
import org.seasar.extension.jdbc.JdbcManager;
import org.seasar.framework.container.SingletonS2Container;
import com.tangosol.net.cache.CacheStore;

public class S2jdbcCacheStore extends S2jdbcCacheLoader implements CacheStore {

/**
* コンストラクタ
* @param entityName 対象となるエンティティ名
* @throws ClassNotFoundException
* @throws InstantiationException
* @throws IllegalAccessException
*/
public S2jdbcCacheStore(String entityName) throws ClassNotFoundException, InstantiationException, IllegalAccessException {
super(entityName);
}

@Override
public void erase(Object arg0) {
// JDBCマネージャの取得
JdbcManager jdbc = SingletonS2Container.getComponent("jdbcManager");
// 削除
jdbc.delete(arg0).execute();
}

@Override
public void store(Object arg0, Object arg1) {
// JDBCマネージャの取得
JdbcManager jdbc = SingletonS2Container.getComponent("jdbcManager");

if (this.load(arg0) != null) {
// 更新
jdbc.update(arg1).execute();
} else {
// 新規作成
jdbc.insert(arg1).execute();
}
}

@SuppressWarnings("rawtypes")
@Override
public void storeAll(Map arg0) {
throw new UnsupportedOperationException();
}

@SuppressWarnings("rawtypes")
@Override
public void eraseAll(Collection arg0) {
throw new UnsupportedOperationException();
}
}

Coherenceの設定ファイル

プロジェクトルートのsrcフォルダ直下にCoherenceS2jdbc.xmlとして作成して下さい。





com.chirokings.entity.*
distributed-s2jdbc




distributed-s2jdbc




LRU
4




com.chirokings.coherence.s2jdbc.S2jdbcCacheStore


java.lang.String {cache-name}









実行クラスのサンプル

package com.chirokings;

import java.math.BigDecimal;
import org.seasar.framework.container.factory.SingletonS2ContainerFactory;
import com.chirokings.entity.Employee;
import com.tangosol.net.CacheFactory;
import com.tangosol.net.NamedCache;

public class CoherenceS2jdbcMain {

public static void main(String[] args) {
//コンテナの初期化
SingletonS2ContainerFactory.init();
//キャッシュの取得
NamedCache cache = CacheFactory.getCache(Employee.class.getName());
//キーの作成
Employee key = new Employee();
key.companyId = "OR";
key.employeId = new BigDecimal(1);
//エンティティの取得
Employee sato = (Employee)cache.get(key);
//年齢の加算
sato.age = sato.age.add(BigDecimal.ONE);
//エンティティの書込み
cache.put(key, sato);
}
}

VM引数

Eclipseの実行構成で下記を指定して下さい。
-Dtangosol.coherence.cacheconfig=CoherenceS2jdbc.xml -Xms512M -Xmx512M -Dtangosol.coherence.localhost=127.0.0.1 -Dtangosol.coherence.ttl=0

参考

Select (S2 Tiger 2.4.43 API)
Overview (Oracle® Coherence Java API Reference)
chirokings: Seasar : Standalone Application+S2JDBC on Eclipse
Oracle® Coherence Developer's Guide Release 3.6.1 Part Number E15723-02