wiki:java/DataNucleus

DataNucleus

O/Rマッパーの1つであるDataNucleusを利用してJPAを利用する方法を紹介します。 基本的には、他のJPAの実装と同じですが、DataNucleusでは、エンハンサによるエンハンス処理をエンティティクラスにかける必要があるので、注意してください。

ここでは、下記のようなディレクトリ構造にファイルがあるものとします。

src/
 +META-INF/
   +persistence.xml
 +org/
   +ultimania/
      +entity/
        +Test.java
 +TestRunner.java

以下、これらのファイルについて説明します。

persistence.xml

DataNucleusに関する設定は、他のJPA実装と同じくpersistence.xmlにて行います。

<?xml version="1.0" encoding="UTF-8" ?>
<persistence version="1.0" xmlns="http://java.sun.com/xml/ns/persistence"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://java.sun.com/xml/ns/persistence
        http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd" >

    <persistence-unit name="dn-unit" transaction-type="RESOURCE_LOCAL">
        <provider>org.datanucleus.jpa.PersistenceProviderImpl</provider>
        <class>org.ultimania.entity.Test</class>
        <properties>
           <property name="javax.persistence.jdbc.driver"  value="org.hsqldb.jdbcDriver"/>  
           <property name="javax.persistence.jdbc.url" value="jdbc:hsqldb:file:./test"/>  
           <property name="javax.persistence.jdbc.user" value="sa"/>  
           <property name="javax.persistence.jdbc.password" value=""/>  
           <property name="javax.jdo.option.Mapping" value="hsql"/>  
           <property name="datanucleus.metadata.validate" value="false"/>  
           <property name="datanucleus.autoCreateSchema" value="true"/>  
           <!-- don't create DELETEME table -->
           <property name="datanucleus.fixeddatastore" value="true"/>  
        </properties>
    </persistence-unit>

</persistence>

DataNucleusを利用する場合、providerに

org.datanucleus.jpa.PersistenceProviderImpl

を指定します。また、javax.jdo.option.MappingプロパティでDBのタイプを指定します。また、

   <property name="datanucleus.fixeddatastore" value="true"/>

この一行を設定しないと、DataNucleusはDELETEMEテーブルを作成し、処理終了時に自動的にデータをロールバックします。処理結果をプログラム終了後もキープしたい場合は、必ずこの1行を入れてください。

Test.java

エンティティは、@Entityアノテーションを利用します。他のJPAと同じです。

package org.ultimania.entity;

import javax.persistence.Basic;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;

@Entity
public class Test {
	@Id
        @GeneratedValue
	int id;
	String name;
	public int getId() {
		return id;
	}
	public void setId(int id) {
		this.id = id;
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
}

Enhancerの実行

DataNucleusは、エンティティクラスをエンハンサでエンハンスして利用する必要があります。エンハンサは、下記のようにして実行します。各jarの細かいバージョンはお使いのDataNucleusのバージョンに合わせてください。

> set DN=<DataNucleusへのインストールパス>
> java -classpath \
%DN%\lib\datanucleus-jpa-2.1.1.jar;%DN%\deps\asm-3.1.jar;%DN%\deps\geronimo-jpa_2.0_spec-1.0.jar;%DN%\deps\jdo-api-3.0.jar;%DN%\lib\datanucleus-core-2.2.0-m1.jar;%DN%\lib\datanucleus-enhancer-2.1.0-release.jar;bin;. \
org.datanucleus.enhancer.DataNucleusEnhancer -api JPA -pu dn-unit

-apiオプションでJPAを、-puオプションでpersistence-unitの名前(name属性で設定した値)を指定します。DataNucleusEnhancer?は、META-INF/persistence.xmlで指定されたエンティティクラスを読み込んで、DataNucleus用の実行コードを埋め込みます。

Eclipseを利用している場合、binディレクトリで上記のコマンドを実行してください。エンティティファイルを変更する都度、エンハンサは実行する必要があります。バッチファイルやシェルスクリプトで簡単に実行できるようにするとよいでしょう。

Entityの利用

次のようにしてEntityを利用します。DataNucleusでは、トランザクションを明示的に利用する必要があるようです。

	EntityManagerFactory emf = Persistence.createEntityManagerFactory("dn-unit");
	EntityManager em = emf.createEntityManager();
	em.getTransaction().begin();
	Test t = new Test();
	t.setId(1);
	t.setName("okamoto");
	em.persist(t);
	em.getTransaction().commit();