2014年1月1日水曜日

JPAを試す(hibernate,eclipselink,openjpa)

JPA といっても規格であってその実装は色々とあるようです。hibernate,openjpa,eclipselink などなど。eclipselink に至っては、eclipse のプラグインか何かだという固定観念が抜けず、JPAだと理解するまでに時間が掛かりました。

JPA関連のクラスを使って例外処理を特に記述しなくてもコンパイルエラーで叱られない理由が良くわからなかったのですが、「JPAの例外はすべてRuntimeExceptionのサブクラスになっています」らしく、「RuntimeExceptionとその子孫クラスは、Java APIがプログラムのバグを検出したときにスローされる特殊な例外であり、キャッチする必要はありませんし、故にJava文法上でもthrows句に列挙しなくてよいことになっています」ということで納得しました。

また、今回からビルドは ant を使ってみることにしました。ツールなのでまずは楽できること主眼として最低限の記載ですませています。後は、実行時に persistence.xml を切り替えることでJPA製品を切り替えて起動確認しています。

JPAを試す(hibernate,eclipse,openjpa)


(1) ディレクトリ構成
$ tree .
.
├── jpatest
│   ├── META-INF
│   │   ├── persistence.xml -> persistence.xml.hibernate
│   │   ├── persistence.xml.eclipselink
│   │   ├── persistence.xml.hibernate
│   │   └── persistence.xml.openjpa
│   ├── foods.class
│   ├── test01.class
│   └── testrun.sh
└── src
    ├── build.xml
    ├── foods.java
    └── test01.java

3 directories, 10 files

(2) foods.java
import java.util.Date;
import java.io.Serializable;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.Table;
import javax.persistence.Temporal;
import javax.persistence.TemporalType;

@Entity
@Table(name="foods")
public class foods implements Serializable {

  public foods(){};

  @Id
  @Column(name="code")
  private String code;

  @Column(name="name")
  private String name;

  @Column(name="price")
  private Integer price;

  public String getCode() {
    return code;
  }

  public void setCode(String code) {
    this.code = code;
  }

  public String getName() {
    return name;
  }

  public void setName(String name) {
    this.name = name;
  }

  public int getPrice() {
    return price;
  }

  public void setPrice(int price) {
    this.price = price;
  }
}

(3) test01.java
import java.util.Date;
import java.util.List;
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.EntityTransaction;
import javax.persistence.Persistence;
import javax.persistence.Query;
import javax.persistence.NoResultException;
import javax.persistence.NonUniqueResultException;
import javax.persistence.EntityManager;

public class test01 {
  public static void main(String args[]) {
    EntityManagerFactory emf =
    Persistence.createEntityManagerFactory("foods");
    EntityManager em = emf.createEntityManager();

    EntityTransaction tran = em.getTransaction();
    tran.begin();

    foods foods1 = em.find(foods.class, "000001");

    System.out.println("コード(変更前):" + foods1.getCode());
    System.out.println("名前(変更前):"   + foods1.getName());
    System.out.println("価格(変更前):"   + foods1.getPrice());

    foods1.setPrice(800);

    foods foods2 = new foods();
    foods2.setCode("000004");
    foods2.setName("巨峰");
    foods2.setPrice(1000);

    em.persist(foods2);

    tran.commit();
    em.close();
    emf.close();
  }
}

(4) build.xml
<?xml version="1.0"?>
<project name="test01" default="default">
  <property name="hibernate" location="/home/naoki/work/java/lib/hibernate/lib" />

  <target name="default">
    <javac srcdir="." destdir="../jpatest" >
      <classpath>
        <pathelement path="${hibernate}/jpa/hibernate-entitymanager-4.3.0.Final.jar" />
        <pathelement path="${hibernate}/required/hibernate-jpa-2.1-api-1.0.0.Final.jar" />
      </classpath>
    </javac>
  </target>
</project>

(5) persistence.xml
・hibernate用
<?xml version="1.0" encoding="UTF-8"?>
<persistence 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"
             version="1.0">

    <persistence-unit name="foods" transaction-type="RESOURCE_LOCAL">
        <provider>org.hibernate.ejb.HibernatePersistence</provider>
        <properties>
            <property name="hibernate.dialect" value="org.hibernate.dialect.MySQLDialect" />
            <property name="javax.persistence.jdbc.driver" value="com.mysql.jdbc.Driver" />
            <property name="javax.persistence.jdbc.user" value="naoki" />
            <property name="javax.persistence.jdbc.password" value="naoki" />
            <property name="javax.persistence.jdbc.url" value="jdbc:mysql://localhost:3306/sampledb" />
<!--
            <property name="hibernate.show_sql" value="true" />
-->
        </properties>
    </persistence-unit>
</persistence>

・eclipselink用
<?xml version="1.0" encoding="UTF-8" ?>
<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_2_0.xsd"
            version="2.0" xmlns="http://java.sun.com/xml/ns/persistence">

    <persistence-unit name="foods" transaction-type="RESOURCE_LOCAL">
        <provider>org.eclipse.persistence.jpa.PersistenceProvider</provider>
        <class>foods</class>
        <properties>
            <property name="javax.persistence.jdbc.driver" value="com.mysql.jdbc.Driver" />
            <property name="javax.persistence.jdbc.url" value="jdbc:mysql://localhost:3306/sampledb" />
            <property name="javax.persistence.jdbc.user" value="naoki" />
            <property name="javax.persistence.jdbc.password" value="naoki" />

            <!-- EclipseLink should create the database schema automatically -->
<!--            <property name="eclipselink.ddl-generation" value="create-tables" /> -->
<!--            <property name="eclipselink.ddl-generation.output-mode" value="database" />  -->
        </properties>
    </persistence-unit>

</persistence>

・openjpa用
<?xml version="1.0" encoding="UTF-8"?>
<persistence xmlns="http://java.sun.com/xml/ns/persistence" version="1.0">
    <!-- For DB connectivity -->
    <persistence-unit name="foods" transaction-type="RESOURCE_LOCAL">
        <provider>org.apache.openjpa.persistence.PersistenceProviderImpl</provider>
        <class>foods</class>
        <properties>
            <property name="openjpa.ConnectionURL" value="jdbc:mysql://localhost:3306/sampledb" />
            <property name="openjpa.ConnectionDriverName" value="com.mysql.jdbc.Driver" />
            <property name="openjpa.ConnectionUserName" value="naoki" />
            <property name="openjpa.ConnectionPassword" value="naoki" />
            <property name="openjpa.jdbc.DBDictionary" value="mysql(SimulateLocking=true)" />
            <property name="openjpa.Log" value="DefaultLevel=WARN, Tool=INFO" />
        </properties>
    </persistence-unit>
</persistence>

(5) コンパイル
% cd src
% ant

(6) 実行シェル
#! /bin/sh 

HIBERNATE_LIST="
/home/naoki/work/java/lib/hibernate/lib/required/hibernate-jpa-2.1-api-1.0.0.Final.jar
/home/naoki/work/java/lib/hibernate/lib/jpa/hibernate-entitymanager-4.3.0.Final.jar
/home/naoki/work/java/lib/hibernate/lib/required/jboss-logging-3.1.3.GA.jar
/home/naoki/work/java/lib/hibernate/lib/required/hibernate-core-4.3.0.Final.jar
/home/naoki/work/java/lib/hibernate/lib/required/jboss-transaction-api_1.2_spec-1.0.0.Final.jar
/home/naoki/work/java/lib/hibernate/lib/required/jandex-1.1.0.Final.jar
/home/naoki/work/java/lib/hibernate/lib/required/javassist-3.18.1-GA.jar
/home/naoki/work/java/lib/hibernate/lib/required/dom4j-1.6.1.jar
/home/naoki/work/java/lib/hibernate/lib/required/hibernate-commons-annotations-4.0.4.Final.jar
/home/naoki/work/java/lib/hibernate/lib/required/antlr-2.7.7.jar
/home/naoki/ダウンロード/mysql-connector-java-5.1.27/mysql-connector-java-5.1.27-bin.jar
.
"

ECLIPSELINK_LIST="
/home/naoki/work/java/lib/eclipselink/utils/dbws/org.eclipse.persistence.oracleddlparser.source_1.0.0.v20121122.jar
/home/naoki/work/java/lib/eclipselink/utils/dbws/javax.wsdl_1.6.2.v201012040545.jar
/home/naoki/work/java/lib/eclipselink/utils/dbws/eclipselink-dbwsutils.jar
/home/naoki/work/java/lib/eclipselink/utils/dbws/javax.servlet_2.4.0.v200806031604.jar
/home/naoki/work/java/lib/eclipselink/utils/dbws/org.eclipse.persistence.oracleddlparser_1.0.0.v20121122.jar
/home/naoki/work/java/lib/eclipselink/utils/rename/package-rename.jar
/home/naoki/work/java/lib/eclipselink/utils/workbench/jlib/xercesImpl.jar
/home/naoki/work/java/lib/eclipselink/utils/workbench/jlib/connector.jar
/home/naoki/work/java/lib/eclipselink/utils/workbench/jlib/elmwcore.jar
/home/naoki/work/java/lib/eclipselink/utils/workbench/jlib/eclipselinkmw.jar
/home/naoki/work/java/lib/eclipselink/jlib/jpa/eclipselink-jpa-modelgen_2.4.2.v20130514-5956486.jar
/home/naoki/work/java/lib/eclipselink/jlib/jpa/javax.persistence_2.0.5.v201212031355.jar
/home/naoki/work/java/lib/eclipselink/jlib/jpa/javax.persistence_1.0.0.jar
/home/naoki/work/java/lib/eclipselink/jlib/jpa/org.eclipse.persistence.jpars_2.4.2.v20130514-5956486.jar
/home/naoki/work/java/lib/eclipselink/jlib/jpa/org.eclipse.persistence.jpars.source_2.4.2.v20130514-5956486.jar
/home/naoki/work/java/lib/eclipselink/jlib/eclipselink.jar
/home/naoki/work/java/lib/eclipselink/jlib/sdo/commonj.sdo_2.1.1.v201112051852.jar
/home/naoki/work/java/lib/eclipselink/jlib/moxy/com.sun.tools.xjc_2.2.0.jar
/home/naoki/work/java/lib/eclipselink/jlib/moxy/javax.xml.bind_2.2.0.v201105210648.jar
/home/naoki/work/java/lib/eclipselink/jlib/moxy/javax.mail_1.4.0.v201005080615.jar
/home/naoki/work/java/lib/eclipselink/jlib/moxy/javax.activation_1.1.0.v201108011116.jar
/home/naoki/work/java/lib/eclipselink/jlib/moxy/com.sun.xml.bind_2.2.0.v201004141950.jar
/home/naoki/work/java/lib/eclipselink/jlib/moxy/javax.xml.stream_1.0.1.v201004272200.jar
/home/naoki/ダウンロード/mysql-connector-java-5.1.27/mysql-connector-java-5.1.27-bin.jar
. 
"

OPENJPA_LIST="
/home/naoki/work/java/lib/openjpa/lib/geronimo-jpa_2.0_spec-1.1.jar
/home/naoki/work/java/lib/openjpa/lib/org.apache.bval.bundle-0.3-incubating.jar
/home/naoki/work/java/lib/openjpa/lib/geronimo-jms_1.1_spec-1.1.1.jar
/home/naoki/work/java/lib/openjpa/lib/commons-beanutils-1.8.3.jar
/home/naoki/work/java/lib/openjpa/lib/commons-logging-1.0.4.jar
/home/naoki/work/java/lib/openjpa/lib/geronimo-jta_1.1_spec-1.1.1.jar
/home/naoki/work/java/lib/openjpa/lib/serp-1.14.1.jar
/home/naoki/work/java/lib/openjpa/lib/geronimo-validation_1.0_spec-1.1.jar
/home/naoki/work/java/lib/openjpa/lib/asm-3.2.jar
/home/naoki/work/java/lib/openjpa/lib/derby-10.8.2.2.jar
/home/naoki/work/java/lib/openjpa/lib/commons-dbcp-1.4.jar
/home/naoki/work/java/lib/openjpa/lib/commons-pool-1.5.4.jar
/home/naoki/work/java/lib/openjpa/lib/commons-lang-2.4.jar
/home/naoki/work/java/lib/openjpa/lib/commons-collections-3.2.1.jar
/home/naoki/work/java/lib/openjpa/openjpa-all-2.2.2.jar
/home/naoki/ダウンロード/mysql-connector-java-5.1.27/mysql-connector-java-5.1.27-bin.jar
.
"

#
rm META-INF/persistence.xml
(cd META-INF;ln -s persistence.xml.hibernate persistence.xml)
CLASSPATH=`echo $HIBERNATE_LIST | sed 's/ /:/g'`
java -cp $CLASSPATH test01

#
#rm META-INF/persistence.xml
#(cd META-INF;ln -s persistence.xml.eclipselink persistence.xml)
#CLASSPATH=`echo $ECLIPSELINK_LIST | sed 's/ /:/g'`
#java -cp $CLASSPATH test01

#
#rm META-INF/persistence.xml
#(cd META-INF;ln -s persistence.xml.openjpa persistence.xml)
#CLASSPATH=`echo $OPENJPA_LIST | sed 's/ /:/g'`
#java -cp $CLASSPATH test01

(7) 実行
$ cd jpatest
$ ./testrun.sh
1 01, 2014 2:01:21 午前 org.hibernate.ejb.HibernatePersistence logDeprecation
WARN: HHH015016: Encountered a deprecated javax.persistence.spi.PersistenceProvider [org.hibernate.ejb.HibernatePersistence]; use [org.hibernate.jpa.HibernatePersistenceProvider] instead.
1 01, 2014 2:01:21 午前 org.hibernate.ejb.HibernatePersistence logDeprecation
WARN: HHH015016: Encountered a deprecated javax.persistence.spi.PersistenceProvider [org.hibernate.ejb.HibernatePersistence]; use [org.hibernate.jpa.HibernatePersistenceProvider] instead.
1 01, 2014 2:01:21 午前 org.hibernate.ejb.HibernatePersistence logDeprecation
WARN: HHH015016: Encountered a deprecated javax.persistence.spi.PersistenceProvider [org.hibernate.ejb.HibernatePersistence]; use [org.hibernate.jpa.HibernatePersistenceProvider] instead.
1 01, 2014 2:01:21 午前 org.hibernate.jpa.internal.util.LogHelper logPersistenceUnitInformation
INFO: HHH000204: Processing PersistenceUnitInfo [
 name: foods
 ...]
1 01, 2014 2:01:21 午前 org.hibernate.Version logVersion
INFO: HHH000412: Hibernate Core {4.3.0.Final}
1 01, 2014 2:01:21 午前 org.hibernate.cfg.Environment 
INFO: HHH000206: hibernate.properties not found
1 01, 2014 2:01:21 午前 org.hibernate.cfg.Environment buildBytecodeProvider
INFO: HHH000021: Bytecode provider name : javassist
1 01, 2014 2:01:21 午前 org.hibernate.annotations.common.reflection.java.JavaReflectionManager 
INFO: HCANN000001: Hibernate Commons Annotations {4.0.4.Final}
1 01, 2014 2:01:21 午前 org.hibernate.engine.jdbc.connections.internal.DriverManagerConnectionProviderImpl configure
INFO: HHH000402: Using Hibernate built-in connection pool (not for production use!)
1 01, 2014 2:01:21 午前 org.hibernate.engine.jdbc.connections.internal.DriverManagerConnectionProviderImpl buildCreator
INFO: HHH000401: using driver [com.mysql.jdbc.Driver] at URL [jdbc:mysql://localhost:3306/sampledb]
1 01, 2014 2:01:21 午前 org.hibernate.engine.jdbc.connections.internal.DriverManagerConnectionProviderImpl buildCreator
INFO: HHH000046: Connection properties: {user=naoki, password=****}
1 01, 2014 2:01:21 午前 org.hibernate.engine.jdbc.connections.internal.DriverManagerConnectionProviderImpl buildCreator
INFO: HHH000006: Autocommit mode: false
1 01, 2014 2:01:21 午前 org.hibernate.engine.jdbc.connections.internal.DriverManagerConnectionProviderImpl configure
INFO: HHH000115: Hibernate connection pool size: 20 (min=1)
1 01, 2014 2:01:22 午前 org.hibernate.dialect.Dialect 
INFO: HHH000400: Using dialect: org.hibernate.dialect.MySQLDialect
1 01, 2014 2:01:22 午前 org.hibernate.hql.internal.ast.ASTQueryTranslatorFactory 
INFO: HHH000397: Using ASTQueryTranslatorFactory
コード(変更前):000001
名前(変更前):りんご(袋詰)
価格(変更前):800
1 01, 2014 2:01:22 午前 org.hibernate.engine.jdbc.connections.internal.DriverManagerConnectionProviderImpl stop
INFO: HHH000030: Cleaning up connection pool [jdbc:mysql://localhost:3306/sampledb]


0 件のコメント:

コメントを投稿