EclipseLinkのセットアップ手順(Tomcat)

EclipseLinkをApache Tomcatで使用する手順です。DBにはApache Derbyを使用して、エンティティを永続化するところまでを説明します。

基本的にはJavaSEの場合と変わりません。ただ、今回はDataSourceを使用して接続することにします。

使用するソフトウェア

Note: Java SE 6、Eclipseのセットアップは説明しません。

Apache Tomcatをダウンロード、セットアップ

Apache Tomcatからファイルをダウンロードして、適当なフォルダに展開します。

Apache Derbyをダウンロード、セットアップ、データベースとテーブルの作成

Apache Derbyからファイルをダウンロードして、適当なフォルダに展開します。

%DERBY%/bin/startNetworkServer.batを実行して、Apache Derbyを起動します。

%DERBY%/bin/ij.batを実行します。connectコマンドを使用して、データベースを作成 & 接続します。

connect 'jdbc:derby://localhost:1527/foo;create=true';

create table文を実行して、テーブルを作成します。

create table foo (
    id integer primary key,
    name varchar(100) not null
);

ついでにテストデータも登録します。

insert into foo values (1, 'one');
insert into foo values (2, 'two');
insert into foo values (3, 'three');

%DERBY%/lib/derbyclient.jarを%TOMCAT%/libフォルダにコピーします。

Note: %TOMCAT%/libフォルダにjarファイルを配置すると、Eclipseのビルド・パスに追加されます。

EclipseLinkをダウンロード、セットアップ

EclipseLinkからファイル(EclipseLink 2.0.0 Installer Zip)をダウンロードして、適当なフォルダに展開します。

次のファイルを%TOMCAT%/libフォルダにコピーします。

  • %ECLIPSELINK%/jlib/eclipselink.jar
  • %ECLIPSELINK%/jlib/jpa/eclipselink-jpa-modelgen_2.0.0.v20091127-r5931.jar
  • %ECLIPSELINK%/jlib/jpa/javax.persistence_1.0.0.jar
  • %ECLIPSELINK%/jlib/jpa/javax.persistence_2.0.0.v200911271158.jar

Eclipseプロジェクトを作成

fooプロジェクトをDynamic Web Projectとして作成します。Target runtimeはApache Tomcat v6.0とします。

Note: 同時にServersプロジェクトが作成されるはずですが、Serversプロジェクトが存在しない場合、とりあえずfooプロジェクトをRun on Serverで実行します。これでServerプロジェクトが作成されます。作成されたらTomcatを停止します。

context.xmlを編集

ServersプロジェクトのTomcat v6.0 Server at localhost-config/context.xmlファイルに、DataSourceの設定を追加します。

<?xml version="1.0" encoding="UTF-8"?>
<Context>

    <WatchedResource>WEB-INF/web.xml</WatchedResource>

    <Resource
        name="ds/foo-ds"
        auth="Container"
        type="javax.sql.DataSource"
        driverClassName="org.apache.derby.jdbc.ClientDriver"
        url="jdbc:derby://localhost:1527/foo"
        username="APP"
        password="APP" />

</Context>

persistence.xmlを作成

ソース・フォルダにMETA-INFフォルダを作成して、その中にpersistence.xmlファイルを作成します(例: src/META-INF/persistence.xml)。WEB-INF/META-INFフォルダが存在していますが、このフォルダでは駄目なので注意してください。

<?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 persistence_1_0.xsd"
    version="1.0">

    <persistence-unit
        name="foo-pu"
        transaction-type="RESOURCE_LOCAL">

        <provider>org.eclipse.persistence.jpa.PersistenceProvider</provider>
        <non-jta-data-source>java:/comp/env/ds/foo-ds</non-jta-data-source>
        <exclude-unlisted-classes>false</exclude-unlisted-classes>

    </persistence-unit>

</persistence>

タグのJNDI URLですが、compの前に/(スラッシュ)が必要です(普通はスラッシュは要らないです)。これを忘れると動作しません。

エンティティを作成

エンティティとして、foo.FooEntityクラスを作成します。

package foo;

import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.Table;

@Entity
@Table(name = "foo")
public class FooEntity {

    @Id
    private int id;

    private String name;

    public int getId() {
        return this.id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getName() {
        return this.name;
    }

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

}

Servletを作成(とりあえず一覧表示)

fooテーブルのデータを一覧表示するServletとしてfoo.FooServletクラスを作成します。

package foo;

import java.io.IOException;
import java.util.List;

import javax.persistence.EntityManager;
import javax.persistence.Persistence;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

@SuppressWarnings("serial")
public class FooServlet extends HttpServlet {

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        EntityManager em = Persistence.createEntityManagerFactory("foo-pu").createEntityManager();
        try {
            List<FooEntity> l = em.createQuery("select e from " + FooEntity.class.getSimpleName() + " e").getResultList();

            String html = "<html><body><table border='1'><tr><th>ID</th><th>Name</th></tr>";
            for (FooEntity foo : l) {
                html += "<tr><td>" + foo.getId() + "</td><td>" + foo.getName() + "</td></tr>";
            }
            html += "</table></body></html>";

            resp.getWriter().write(html);
        } finally {
            em.close();
        }
    }

}

web.xmlを編集

web.xmlファイルに、Servletの設定、及びDataSourceの設定を記述します。

<?xml version="1.0" encoding="UTF-8"?>
<web-app
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns="http://java.sun.com/xml/ns/javaee"
    xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
    xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
    id="WebApp_ID"
    version="2.5">

    <servlet>
        <servlet-name>FooServlet</servlet-name>
        <servlet-class>foo.FooServlet</servlet-class>
    </servlet>

    <servlet-mapping>
        <servlet-name>FooServlet</servlet-name>
        <url-pattern>/foo</url-pattern>
    </servlet-mapping>

</web-app>

動作確認(一覧表示)

Tomcatを起動して、Webブラウザhttp://localhost:8080/foo/fooにアクセスします。

次のように一覧表示されれば正常動作しています。


Note: 正常動作しない場合、例外のメッセージをよく読みましょう。ありがちなミスとして次のようなものがあります。

  • NoClassDefFoundError例外が発生 - 必要なjarファイルがTomcatのクラスパスに存在しない。
  • DB接続に失敗 - DataSourceの設定がおかしい。

Servletを作成(データ登録)

一覧表示するServletを作ったので、今度はデータを登録するServletを作成します。リクエスト・パラメータからIDとNameを取得してfooテーブルに登録して、/fooにフォワードするfoo.BarServlerクラスを作成します。

package foo;

import java.io.IOException;

import javax.persistence.EntityManager;
import javax.persistence.Persistence;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

@SuppressWarnings("serial")
public class BarServlet extends HttpServlet {

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        int id = Integer.parseInt(req.getParameter("id"));
        String name = req.getParameter("name");

        EntityManager em = Persistence.createEntityManagerFactory("foo-pu").createEntityManager();
        try {
            em.getTransaction().begin();

            FooEntity foo = new FooEntity();
            foo.setId(id);
            foo.setName(name);

            em.persist(foo);

            em.getTransaction().commit();
        } finally {
            if (em.getTransaction().isActive()) {
                em.getTransaction().rollback();
            }

            em.close();
        }

        this.getServletContext().getRequestDispatcher("/foo").forward(req, resp);
    }

}

web.xmlを編集

web.xmlファイルを編集して、foo.BarServletクラスの設定を追加します。

<servlet>
    <servlet-name>BarServlet</servlet-name>
    <servlet-class>foo.BarServlet</servlet-class>
</servlet>

<servlet-mapping>
    <servlet-name>BarServlet</servlet-name>
    <url-pattern>/bar</url-pattern>
</servlet-mapping>

動作確認(データ登録 -> 一覧表示)

Tomcatを起動して、Webブラウザhttp://localhost:8080/foo/bar?id=4&name=fourにアクセスします。

次のように表示されれば正常動作しています。

DBの内容も確認してみます。ID=4のデータが登録されているはずです。

ij> select * from foo;
ID         |NAME
-------------------------------
1          |one
2          |two
3          |three
4          |four

4 行が選択されました