EclipseでJPA(Java Persistence API)

## はじめに
JPAのサンプルプログラムをEclipseで作ってみます。
[MVCプログラム](https://qiita.com/0ashina0/items/7c378823905949b301af)を改造し、JPAを使ってPostgre SQLのDBからデータを取得します。
あらかじめEmplyeeテーブルを作成しておきます。(参照:[Postgre SQLをインストールする](https://qiita.com/0ashina0/items/6574a9e417aff2d86177))

## 開発環境
Windows 10 Pro 1709(16299.192)
Eclipse pleiades-4.7.3
java 1.8.0_162
PostgreSQL 10.4 Released!

## 手順
１．PostgreSQL JDBC Driver のダウンロード

２．プロジェクトのWEB-INF\libにコピー

３．Postgres SQLへの接続作成

４．JPAプロジェクトへ変換

５．ソースコードの変更

６．動作確認

## １．PostgreSQL JDBC Driver のダウンロード
### URL

```
https://jdbc.postgresql.org/download.html
```

#### 1. 「PostgreSQL JDBC 4.2 Driver, 42.2.2」クリック
![image.png](https://qiita-image-store.s3.amazonaws.com/0/214982/3e8eb8ac-8317-f3e7-9fe3-1df60712dc18.png)

## ２．プロジェクトのWEB-INF\libにコピー
![image.png](https://qiita-image-store.s3.amazonaws.com/0/214982/975ddc1f-c27a-e884-6478-f9d2bee58b13.png)


## ３．Postgres SQLへの接続作成

#### 1. 「ウィンドウ」 -> 「ビューの表示」 -> 「その他」メニュー選択

![image.png](https://qiita-image-store.s3.amazonaws.com/0/214982/8e92b7d8-7cbb-ee99-8307-5e1288388651.png)

#### 2. 「データ管理」「データ・ソース・エクスプローラー」を選択し、「開く」をクリック

![image.png](https://qiita-image-store.s3.amazonaws.com/0/214982/35c6a2e9-4c40-8605-d4bd-86f050f44ebf.png)

#### 3. 「データソース接続」上で右メニュー、「新規」をクリック

![image.png](https://qiita-image-store.s3.amazonaws.com/0/214982/48f8852a-82d1-9cf9-e548-4ad79044a3aa.png)

#### 4. 「Postgres SQL」を選択し、「次へ」をクリック

![image.png](https://qiita-image-store.s3.amazonaws.com/0/214982/c76e4531-9523-6327-d222-a2cd526d6964.png)

#### 5. 「データベース」「URL」「ユーザ名」「パスワード」を入力し、「接続のテスト」をクリック

#### 6. 「Pingが正常に完了しました」を確認し、「OK」ボタンをクリック

#### 7. 「完了」ボタンをクリック

![image.png](https://qiita-image-store.s3.amazonaws.com/0/214982/58e2476d-27e4-558d-3830-5e6f8e2e84d7.png)

#### 8. [Postgre SQLをインストールする](https://qiita.com/0ashina0/items/6574a9e417aff2d86177)で作成したテーブルが確認できる

![image.png](https://qiita-image-store.s3.amazonaws.com/0/214982/badc58ad-2b10-42ec-aac1-e375c74e7f2b.png)


## ４．JPAプロジェクトへ変換

#### 1. プロジェクト上で右メニュ -> 構成 -> JPAプロジェクトへ変換を選択

![image.png](https://qiita-image-store.s3.amazonaws.com/0/214982/9eb9f7f7-cc45-cb1e-9195-6a8d3ec1db6b.png)

#### 2. 「次へ」クリック

![image.png](https://qiita-image-store.s3.amazonaws.com/0/214982/1eb45c70-ccca-ea28-ec1a-62d5b825a9c0.png)

#### 3. 「EclipseLink 2.5.2」を選択し、「次へ」クリック

![image.png](https://qiita-image-store.s3.amazonaws.com/0/214982/686cb80b-8051-5e77-7ac5-0c634458b0f8.png)

#### 4. 「このライセンスの条項に受託」をチェックし、「完了」クリック

![image.png](https://qiita-image-store.s3.amazonaws.com/0/214982/538c60e9-a301-a8dd-bd44-fc45eca69132.png)

#### 5. 「新規 PostgreSQL」の接続を選択し、「ビルド・パス」「接続からデフォルト・カタログを上書き」「接続からデフォルト・スキーマをオーバーライド」をチェックし、「完了」クリック

![image.png](https://qiita-image-store.s3.amazonaws.com/0/214982/9f8c28bb-168a-fdc1-4b37-9a59c52db06e.png)

#### 6. プロジェクト上で右メニュ -> JPAツール -> テーブルからエンティティーを生成を選択

![image.png](https://qiita-image-store.s3.amazonaws.com/0/214982/dbb110b0-e4f0-53a8-12ad-49a4c0640f41.png)

#### 7. 「employee」テーブルにチェックし、「完了」クリック

![image.png](https://qiita-image-store.s3.amazonaws.com/0/214982/bb1198a1-43f0-180b-2012-a91b03b51592.png)

## ５．ソースコードの変更

#### 1. Employee Entityに、findByIdの@NamedQuery を追加
```
変更前

@Entity
@NamedQuery(name="Employee.findAll", query="SELECT e FROM Employee e")
public class Employee implements Serializable {
```
```
変更後

@Entity
@NamedQueries({
	@NamedQuery(name="Employee.findAll", query="SELECT e FROM Employee e"),
	@NamedQuery(name = "Employee.findById", query = "SELECT e from Employee e where e.id = :id")
})
public class Employee implements Serializable {
```

#### 2. EmployeeServletを、DBから取得するよう変更

```
変更後

package emp;

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

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

import model.Employee;


/**
 * Servlet implementation class EmployeeServlet
 */
@WebServlet(name = "EmpList", urlPatterns = { "/EmpList" })
public class EmployeeServlet extends HttpServlet {
	private static final long serialVersionUID = 1L;

    /**
     * @see HttpServlet#HttpServlet()
     */
    public EmployeeServlet() {
        super();
    }

	/**
	 * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
	 */
	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

		EntityManagerFactory emf = Persistence.createEntityManagerFactory("SampleMVC2");
		EntityManager entityManager = emf.createEntityManager();

        List<Employee> employeeList = entityManager
                .createNamedQuery("Employee.findAll", Employee.class)
                .getResultList();

        entityManager.close();
        emf.close();


	    // ViewへModelデータを渡す
	    request.setAttribute("employeeList", employeeList);

	    // Viewを表示
	    this.getServletContext()
	        .getRequestDispatcher("/employeeList.jsp")
	        .forward(request, response);
	}

	/**
	 * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
	 */
	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

		EntityManagerFactory emf = Persistence.createEntityManagerFactory("SampleMVC2");
		EntityManager entityManager = emf.createEntityManager();

		List<Employee> employeeList;

		String id = request.getParameter("id");

		if (id.isEmpty()) {
	        employeeList = entityManager
	                .createNamedQuery("Employee.findAll", Employee.class)
	                .getResultList();
		}
		else {
	        employeeList = entityManager
	                .createNamedQuery("Employee.findById", Employee.class)
	                .setParameter("id", id)
	                .getResultList();
		}

        entityManager.close();
        emf.close();

        // ViewへModelデータを渡す
		request.setAttribute("employeeList", employeeList);


		// Viewを表示
	    this.getServletContext()
	        .getRequestDispatcher("/employeeList.jsp")
	        .forward(request, response);

	}

}
```

#### 3. EmployeeBean上で右メニュー -> 「削除」選択

![image.png](https://qiita-image-store.s3.amazonaws.com/0/214982/ef8ad53c-e656-6e2f-3095-a1d06dac4e15.png)

#### 4. 「OK」選択

![image.png](https://qiita-image-store.s3.amazonaws.com/0/214982/19fc1d74-d16e-c771-946a-7ba8e4062325.png)

#### 5. 「persistence.xml」変更

```
変更前

<?xml version="1.0" encoding="UTF-8"?>
<persistence version="2.1" xmlns="http://xmlns.jcp.org/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/persistence http://xmlns.jcp.org/xml/ns/persistence/persistence_2_1.xsd">
	<persistence-unit name="SampleMVC">
		<class>model.Employee</class>
	</persistence-unit>
</persistence>
```
```
変更後（DB接続情報追加）

<?xml version="1.0" encoding="UTF-8"?>
<persistence version="2.1" xmlns="http://xmlns.jcp.org/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/persistence http://xmlns.jcp.org/xml/ns/persistence/persistence_2_1.xsd">
	<persistence-unit name="SampleMVC2">
		<class>model.Employee</class>
		<properties>
			<property name="javax.persistence.jdbc.driver" value="org.postgresql.Driver" /> <!-- DB Driver -->
			<property name="javax.persistence.jdbc.url" value="jdbc:postgresql://localhost/postgres" /> <!-- BD Mane -->
			<property name="javax.persistence.jdbc.user" value="postgres" /> <!-- DB User -->
			<property name="javax.persistence.jdbc.password" value="dev" /> <!-- DB Password -->
		</properties>
	</persistence-unit>
</persistence>

```



## ６．動作確認

[「Eclipse で MVC.」の動作確認参照](https://qiita.com/0ashina0/items/7c378823905949b301af#4-%E5%8B%95%E4%BD%9C%E7%A2%BA%E8%AA%8D)


## おわりに
- EntityManagerにアノテーション@PersistenceContextを付与できるのは、トランザクション管理（コンテナ管理）されているときのみ。そうでない場合は@PersistenceContextは無視される。