かずきのBlog

C#やJavaやRubyとメモ書き

目次

Blog 利用状況

ニュース

わんくまBlogが不安定になったため、前に書いてたはてなダイアリーにメインを移動します。
かずきのBlog@Hatena
技術的なネタは、こちらにも、はてなへのリンクという形で掲載しますが、雑多ネタははてなダイアリーだけに掲載することが多いと思います。
コメント
プログラマ的自己紹介
お気に入りのツール/IDE
プロフィール
経歴
広告
アクセサリ

書庫

日記カテゴリ

[NetBeans][Java]Spring Framework 2.5 とJPAの連携

久しくさぼってたSpring Frameworkですが、NetBeans 6.7 Beta版が出たのでつっついてみたいと思います。
今日のお題はSpring Framework + JPAを試してみようと思います。

データベースの作成

とりあえず、お試しようのデータベースを作成します。
SpringとJPAの連携がメインなので、DBはシンプルに外部キーとかのない1テーブルのみのDBにします。

サーバウィンドウのデータベースの下のJavaDBで右クリックしてデータベースを作成を選択します。
image

DB名、ユーザ名、パスワードすべてjpaeduのデータベースを作成します。
image

DBが作成されると、DBの接続も出来るので右クリックして接続を選択します。
image

APPの下の表の右クリックメニューからコマンドを実行を選択します。
image 

以下のSQLを打ち込んで実行してテスト用のテーブルを作成します。

create table Person (
    id int primary key,
    name varchar(255));

以上でDBの作成は完了です。

プロジェクトの作成

DBの準備が終わったので、Javaのプロジェクトを作成していきます。
springjpaeduという名前で、Java アプリケーションのプロジェクトを作成します。

エンティティクラスの作成

プロジェクトを作成したら、springjpaedu.entitiesというパッケージを作成して、そこに新規→データベースからのエンティティクラスを選択してエンティティクラスを作成します。
image

先ほど作ったjpaeduデータベースを選択して、PERSONテーブルを選択します。
image

次の画面で、持続性ユニットを作成を選択して持続性ユニットを作成します。
image

持続性ユニットを作成したら、その他の項目はデフォルトのまま作成します。
作成が完了すると、springjpaedu.entities.Personクラスが作成されます。
image

作成されたら、ちゃんと動くかの確認も兼ねて、テスト用データ作成プログラムを作ります。
JPAを使うこと自体が主題ではないので、プログラムだけのせます。
とりあえずDBをクリアして、1000件データを作成しているだけのプログラムです。

package springjpaedu;

import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.EntityTransaction;
import javax.persistence.Persistence;
import springjpaedu.entities.Person;

public class Main {

    private static final String PU = "springjpaeduPU";

    public static void main(String[] args) {
        EntityManagerFactory emf = null;
        EntityManager em = null;
        try {
            emf = Persistence.createEntityManagerFactory(PU);
            em = emf.createEntityManager();
            execute(em);
        } finally {
            if (em != null) {
                em.close();
            }
            if (emf != null) {
                emf.close();
            }
        }
    }

    private static void execute(EntityManager em) {
        EntityTransaction tx = em.getTransaction();
        try {
            tx.begin();
            int deleted = em.createQuery("delete from Person").executeUpdate();
            for (int i = 1; i <= 1000; i++) {
                Person p = new Person();
                p.setId(i);
                p.setName("田中 太郎" + i);
                em.persist(p);
            }
            tx.commit();
            System.out.println(deleted + "件のデータを削除しました");
            System.out.println("1000件のデータを作成しました");
        } catch (RuntimeException e) {
            tx.rollback();
            System.out.println("失敗");
            e.printStackTrace();
        }
    }
}

このまま実行すると、恐らくエラーがおきてしまいます。
JavaDBのJDBCドライバをライブラリについかしていないのが原因なので、JavaDBのドライバをライブラリに追加します。

最近のJavaを何も意識せずに入れていると、C:\Program Files\Sun\JavaDB\lib\derbyclient.jarにJavaDBのJDBCドライバがあるので、それをライブラリに追加します。

実行すると、↓のような文字列が出力ウィンドウに表示されるはずです。

run:
[EL Info]: 2009.05.17 18:35:44.959--ServerSession(25197736)--EclipseLink, version: Eclipse Persistence Services - 1.0.1 (Build 20080905)
[EL Info]: 2009.05.17 18:35:45.118--ServerSession(25197736)--file:/C:/Users/Kazuki/Documents/NetBeansProjects/springjpaedu/src/-springjpaeduPU login successful
0件のデータを削除しました
1000件のデータを作成しました
[EL Info]: 2009.05.17 18:35:46.252--ServerSession(25197736)--file:/C:/Users/Kazuki/Documents/NetBeansProjects/springjpaedu/src/-springjpaeduPU logout successful
構築成功 (合計時間: 2 秒)

Springの設定

ついにSpring Frameworkのほうに入ります!
まず、ライブラリからSpring Framework 2.5を選択して追加します。これには、以下の3つのjarファイルが含まれています。

  1. spring-2.5.jar
  2. cglib-2.2.jar
  3. commons-logging-1.1.jar

凝ったことをしないのであればこれでいいのですが、今回はちょっとこれだけだと都合が悪いので、aspectjrt.jarもライブラリに追加します。
これは、Spring Frameworkのページから一式入ったものをダウンロードした中に入っているので、それを追加しました。
image

つぎに、このspringjpaedu.DaoTestMainクラスを作成して、mainメソッドを作っておきます。

package springjpaedu;

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

public class DaoTestMain {

    public static void main(String[] args) {
        AbstractApplicationContext ctx = null;
        try {
            ctx = new ClassPathXmlApplicationContext("applicationContext.xml");
            // TODO : ここに処理を書いていく予定
        } finally {
            ctx.close();
        }
    }
}

次に、デフォルトパッケージにapplicationContext.xmlを作成します。ソースパッケージの右クリックメニューから新規→その他からSpring XML 構成ファイルを選択します。
image

ファイル名をapplicationContext(xmlはつけない)にして次へ
image

名前空間には、contextとtxを選んで完了を押してください。
image

DaoTestMainを実行して、エラーが出ないことを確認すれば下準備完了です。

やっとDAO

ついにSpringとJPAの連携の機能を作りこんでいきます!長かった…

Spring FrameworkとJPAの連携は、2通りの方法があります。

  1. Hibernateとかと同じように***DaoSupportと***Templateクラスを使う方法
  2. JPAのAPIをそのまま使う方法

今回は2番のJPAのAPIをそのまま使う方法をやってみます。
何故かというと、1の方法でもあまりうれしさが感じれないからです。Hibernateとかで経験がある人が、自然に使いはじめれるという利点があるくらいなのかな?

とりあえずDAOを作っていきます!

springjpaedu.daoパッケージを作成して、そこにPersonDaoインターフェースとPersonDaoImplクラスを作成します。

PersonDaoに、CRUD用のメソッドを一通り作成します。

package springjpaedu.dao;

import java.util.List;
import springjpaedu.entities.Person;

public interface PersonDao {
    List<Person> findAll();
    Person get(int id);
    void update(Person p);
    void insert(Person p);
    void delete(Person p);
}

PersonDaoImplで、これを実装していきます。

package springjpaedu.dao;

import java.util.List;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import org.springframework.stereotype.Repository;
import org.springframework.transaction.annotation.Transactional;
import springjpaedu.entities.Person;

// トランザクションの定義
@Transactional
// Springに自動登録してもらうための印
@Repository("personDao")
public class PersonDaoImpl implements PersonDao {

    // PersistenceContextをつけておくとSpringが適切にインスタンスをセットしてくれる
    @PersistenceContext
    private EntityManager entityManager;

    @Transactional(readOnly=true)
    public List<Person> findAll() {
        return entityManager.
                createQuery("select p from Person p order by p.id").
                getResultList();
    }

    // 以下のメソッドでEntityManagerを使って色々処理を書く
    @Transactional(readOnly=true)
    public Person get(int id) {
        return entityManager.find(Person.class, id);
    }

    public void update(Person p) {
        entityManager.merge(p);
    }

    public void insert(Person p) {
        entityManager.persist(p);
    }

    public void delete(Person p) {
        entityManager.remove(p);
    }

}

特別なことは別にしてなくて、EJB3のコンテナでもそのまま動きそう。

これを使うようにSpringの定義ファイルを書いていきます。

<?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"
       xmlns:tx="http://www.springframework.org/schema/tx"
       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
       http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.5.xsd">
    <!-- EntityManagerFactoryとTransactionManagerを定義 -->
    <bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalEntityManagerFactoryBean">
        <property name="persistenceUnitName" value="springjpaeduPU" />
    </bean>
    <bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
        <property name="entityManagerFactory" ref="entityManagerFactory" />
    </bean>

    <!-- JPAの例外をSpringの例外に変換してくれる -->
    <bean class="org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor" />
    <!-- PersistenceContextアノテーションにEntityManagerをインジェクションしてくれる -->
    <bean class="org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor" />

    <!-- DAOを自動登録(今回の場合1つしかないからあまりありがたみは無いかも -->
    <context:component-scan base-package="springjpaedu.dao" />

    <!-- アノテーションベースのトランザクション制御 -->
    <tx:annotation-driven />
</beans>

こいつが動くかどうか簡単に確認してみようと思います。
動作を確認するために、CRUDを一通りするプログラムを作成してみました。

package springjpaedu;

import java.util.List;
import org.springframework.context.support.AbstractApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import springjpaedu.dao.PersonDao;
import springjpaedu.entities.Person;

public class DaoTestMain {

    public static void main(String[] args) {
        AbstractApplicationContext ctx = null;
        try {
            ctx = new ClassPathXmlApplicationContext("applicationContext.xml");
            PersonDao dao = (PersonDao) ctx.getBean("personDao");
            
            // 全件表示
            List<Person> people = dao.findAll();
            System.out.println("## 全データ出力");
            System.out.println(people);

            // 1件取得して更新
            Person p = dao.get(1);
            p.setName("田中 麻呂");
            dao.update(p);

            // 更新された値を確認
            Person p2 = dao.get(1);
            System.out.println("更新後の名前: " + p2.getName());

            // 新しい人を登録
            Person newPerson = new Person();
            newPerson.setId(1001);
            newPerson.setName("木村 きむきむ");
            dao.insert(newPerson);

            // 新しく登録された人を確認
            Person newPerson2 = dao.get(1001);
            System.out.println("追加した人の名前: " + newPerson2.getName());
        } finally {
            ctx.close();
        }
    }
}

実行すると

## 全データ出力
[springjpaedu.entities.Person[id=1], springjpaedu.entities.Person[id=2], springjpaedu.entities.Person[id=3], spri...省略]
更新後の名前: 田中 麻呂
追加した人の名前: 木村 きむきむ

ちゃんと更新とかもされているっぽいです。
META-INF/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="springjpaeduPU" transaction-type="RESOURCE_LOCAL">
    <provider>org.eclipse.persistence.jpa.PersistenceProvider</provider>
    <class>springjpaedu.entities.Person</class>
    <properties>
      <property name="eclipselink.jdbc.password" value="jpaedu"/>
      <property name="eclipselink.jdbc.user" value="jpaedu"/>
      <property name="eclipselink.jdbc.driver" value="org.apache.derby.jdbc.ClientDriver"/>
      <property name="eclipselink.jdbc.url" value="jdbc:derby://localhost:1527/jpaedu"/>
      <!-- SQLのログを出力 -->
      <property name="eclipselink.logging.level" value="FINE" />
    </properties>
  </persistence-unit>
</persistence>

実際に発行されているSQL文も表示されていい感じになりそうです。
データ作成用のMainを起動してDBを初期化して、Javaのファイル以外を更新したので生成物を削除して構築をしてDaoTestMainを実行すると…

[EL Fine]: 2009.05.17 23:08:16.602--ServerSession(2719739)--Connection(6586390)--Thread(Thread[main,5,main])--SELECT ID, NAME FROM PERSON ORDER BY ID ASC
## 全データ出力
[springjpaedu.entities.Person[id=1], springjpaedu.entities.Person[id=2], springjpaedu.entities.Person[id=3], springjpaedu.entities.Person[id=4], springjp...省略]]
[EL Fine]: 2009.05.17 23:08:16.802--ClientSession(20804180)--Connection(27660658)--Thread(Thread[main,5,main])--UPDATE PERSON SET NAME = ? WHERE (ID = ?)
        bind => [田中 麻呂, 1]
更新後の名前: 田中 麻呂
[EL Fine]: 2009.05.17 23:08:16.809--ClientSession(24809582)--Connection(9870377)--Thread(Thread[main,5,main])--INSERT INTO PERSON (ID, NAME) VALUES (?, ?)
        bind => [1001, 木村 きむきむ]
追加した人の名前: 木村 きむきむ

うん。大丈夫そう。

投稿日時 : 2009年5月17日 23:12

Feedback

#  NetBeans ??? Spring Framework ???????????? - Technology 2009/08/25 0:02 Pingback/TrackBack

NetBeans ??? Spring Framework ???????????? - Technology

# sacs lancel 2012/10/19 13:15 http://www.saclancelpascher2013.com

As soon as I observed this site I went on reddit to share some of the love with them.

# louis vuitton handbags 2012/10/28 2:50 http://www.louisvuittonoutletbags2013.com/

Certainly not frown, virtually all you could be heartbreaking, sinse you can never predict that's diminishing crazy about your personal laugh.
louis vuitton handbags http://www.louisvuittonoutletbags2013.com/

# louis vuitton shoes 2012/10/28 2:50 http://www.louisvuittonwallets2013.com/

Around the globe maybe you are an individual, but yet to just one woman / man maybe you are the world.
louis vuitton shoes http://www.louisvuittonwallets2013.com/

# louis vuitton outlet 2012/10/28 2:51 http://www.louisvuittonoutletdiaperbag.com/

Put on‘l make an effort so difficult, a great objects may be purchased whilst you the bare minimum assume them to.
louis vuitton outlet http://www.louisvuittonoutletdiaperbag.com/

# womens shirts 2012/10/28 15:57 http://www.burberryoutletscarfsale.com/burberry-wo

But a smiling visitant here to share the love (:, btw outstanding style and design. "The price one pays for pursuing a profession, or calling, is an intimate knowledge of its ugly side." by James Arthur Baldwin.
womens shirts http://www.burberryoutletscarfsale.com/burberry-womens-shirts.html

# clarisonic mia Sale 2012/10/30 21:06 http://www.clarisonicmia-coupon.com/

Tend not to socialize who ? re secure to get along with. Connect with others who'll energy want you to jimmy your true self themsleves.
clarisonic mia Sale http://www.clarisonicmia-coupon.com/

# burberry outlet store 2012/11/03 0:21 http://www.burberrysalehandbags.com

You are my breathing in, I own few blogs and occasionally run out from post :). "To die for a religion is easier than to live it absolutely." by Jorge Luis Borges.
burberry outlet store http://www.burberrysalehandbags.com

# t shirt scarf 2012/11/03 0:21 http://www.burberrysalehandbags.com/burberry-scarf

I really enjoy studying on this website , it has excellent blog posts. "A man of genius has been seldom ruined but by himself." by Samuel Johnson.
t shirt scarf http://www.burberrysalehandbags.com/burberry-scarf.html

# t shirts 2012/11/03 0:21 http://www.burberrysalehandbags.com/burberry-women

Merely wanna tell that this is invaluable , Thanks for taking your time to write this.
t shirts http://www.burberrysalehandbags.com/burberry-womens-shirts.html

# burberry wallets 2012/11/03 0:21 http://www.burberrysalehandbags.com/burberry-walle

Regards for helping out, great info. "You must do the things you think you cannot do." by Eleanor Roosevelt.
burberry wallets http://www.burberrysalehandbags.com/burberry-wallets-2012.html

# cheap tie 2012/11/03 0:21 http://www.burberrysalehandbags.com/burberry-ties.

Hello, Neat post. There is a problem along with your web site in web explorer, would check this… IE nonetheless is the market chief and a huge portion of other folks will omit your excellent writing due to this problem.
cheap tie http://www.burberrysalehandbags.com/burberry-ties.html

# burberry bag 2012/11/03 1:27 http://www.burberryoutletscarfsale.com/burberry-ba

I dugg some of you post as I cogitated they were very beneficial very beneficial
burberry bag http://www.burberryoutletscarfsale.com/burberry-bags.html

# wallet 2012/11/03 1:27 http://www.burberryoutletscarfsale.com/accessories

I'll immediately grasp your rss feed as I can not find your email subscription hyperlink or e-newsletter service. Do you've any? Please let me recognize in order that I could subscribe. Thanks.
wallet http://www.burberryoutletscarfsale.com/accessories/burberry-wallets-2012.html

# scarf 2012/11/03 1:27 http://www.burberryoutletscarfsale.com/accessories

Some really fantastic blog posts on this website , regards for contribution.
scarf http://www.burberryoutletscarfsale.com/accessories/burberry-scarf.html

# wFLZPqGPUjLaAKVGIV 2018/12/17 7:53 https://www.suba.me/

Q1Mxse Very neat blog.Much thanks again. Fantastic.

# rWtpUuIiDccyb 2018/12/19 22:57 https://www.suba.me/

37TvKX Major thankies for the blog post.Really looking forward to read more. Will read on...

# tQoxMQoiWmp 2021/07/03 2:41 https://amzn.to/365xyVY

There is noticeably a bundle to know about this. I assume you made certain good points in features also.

# YoxFhTdSHtbOZAJmFQJ 2021/07/03 4:10 https://www.blogger.com/profile/060647091882378654

Im obliged for the blog article.Really looking forward to read more.

# EKrFXizITWW 2022/04/19 13:39 johnansog

http://imrdsoacha.gov.co/silvitra-120mg-qrms

タイトル
名前
Url
コメント