概要
GrassFishでJPAのEntityManagerをインジェクションしようとすると、デプロイ時にエラーでハマったのでメモ
環境
key | value |
---|---|
OS | Windows10 |
IDE | IntelliJ IDEA Ultimate |
JDK | JDK8 |
JavaEEサーバ | GrassFish5.0 |
JPAプロバイダ | EclipseLink |
ビルドツール | Maven |
DB | MySQL5.7 |
事象
JAX-RSとJPAでRESTful APIを作っていたら、実行(WARのデプロイ時)にエラー
[2019-09-20 04:25:26,873] Artifact rest:war: Error during artifact deployment. See server log for details.
サーバログで詳細を確認しろとのこと
GrassFishLog
[2019-09-20T16:28:08.474+0900] [glassfish 5.0] [SEVERE] [] [javax.enterprise.system.core] [tid: _ThreadID=54 _ThreadName=admin-listener(5)] [timeMillis: 1568964488474] [levelValue: 1000] [[
Exception while deploying the app [rest] : Exception [EclipseLink-4002] (Eclipse Persistence Services - 2.7.0.v20170811-d680af5): org.eclipse.persistence.exceptions.DatabaseException
Internal Exception: java.sql.SQLException: Error in allocating a connection. Cause: Connection could not be allocated because: java.net.ConnectException: ポート1,527のサーバーlocalhostへの接続中にメッセージConnection refused: connectでエラーが発生しました。
Error Code: 0]]
なにやらSQLの接続でエラーが発生しているが、デプロイ時にSQL?ポート1527?で混乱
状態
ArticleResource.java
package com.example.resource;
import com.example.entity.ArticleEntity;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;
@Path("/article")
public class ArticleResource2 {
// アノテーションでインジェクションしようとするとエラー
@PersistenceContext(unitName = "NewPersistenceUnit")
EntityManager em;
@GET
@Path("/{articleId}")
@Produces(MediaType.APPLICATION_JSON)
public ArticleEntity getArticle(@PathParam("articleId") int articleId) {
// ここでnewすればエラーは発生しない
// EntityManager em = Persistence.createEntityManagerFactory("NewPersistenceUnit").createEntityManager();
ArticleEntity article = em.find(ArticleEntity.class, articleId);
return article;
}
}
persistence.xml
<?xml version="1.0" encoding="UTF-8"?>
<persistence xmlns="http://xmlns.jcp.org/xml/ns/persistence" version="2.1">
<persistence-unit name="NewPersistenceUnit">
<provider>org.eclipse.persistence.jpa.PersistenceProvider</provider>
<class>com.example.entity.ArticleEntity</class>
<properties>
<property name="eclipselink.jdbc.url" value="jdbc:mysql://localhost:3306?serverTimezone=Asia/Tokyo"/>
<property name="eclipselink.jdbc.driver" value="com.mysql.jdbc.Driver"/>
<property name="eclipselink.jdbc.user" value="xxx"/>
<property name="eclipselink.jdbc.password" value="xxx"/>
</properties>
</persistence-unit>
</persistence>
対応
1. GrassFishにJDBCドライバを配置
- 配置場所:
C:\Users\<GrassFishのインストールフォルダ>\glassfish\domains\domain1\lib\ext
- JDBCドライバ:
mysql-connector-java-8.0.15.jar
2. GrassFishの管理コンソールからJDBC接続プールとJDBCリソースを作成
設定内容
<JDBC接続プール>
- Pool Name: mysqlPool
- Resource Type: javax.sql.DataSource
- Datasource Classname: com.mysql.cj.jdbc.MysqlDataSource ←mysql-connectorが5系の場合と異なるので注意
- Additional Properties:
serverName: localhost
serverTimezone: Asia/Tokyo ←タイムゾーンの指定がないとエラーになったので追加
databaseName: blog
user: xxx
password: xxx
<JDBCリソース>
- JNDI Name: jdbc/mysql
- Pool Name: mysqlPool
3. persisitence.xmlに設定を追加
persistence.xml(修正後)
<?xml version="1.0" encoding="UTF-8"?>
<persistence xmlns="http://xmlns.jcp.org/xml/ns/persistence" version="2.1">
<persistence-unit name="NewPersistenceUnit">
<provider>org.eclipse.persistence.jpa.PersistenceProvider</provider>
<!-- JTAデータソースの設定を追加 -->
<jta-data-source>jdbc/mysql</jta-data-source>
<class>com.example.entity.ArticleEntity</class>
<properties>
<property name="eclipselink.jdbc.url" value="jdbc:mysql://localhost:3306?serverTimezone=Asia/Tokyo"/>
<property name="eclipselink.jdbc.driver" value="com.mysql.jdbc.Driver"/>
<property name="eclipselink.jdbc.user" value="xxx"/>
<property name="eclipselink.jdbc.password" value="xxx"/>
</properties>
</persistence-unit>
</persistence>
参考になったサイト(JDBC接続プールとJDBCリソースの追加方法など)
http://niwaka.hateblo.jp/entry/2015/02/25/215731
http://masatoshitada.hatenadiary.jp/entry/2014/12/04/191337
https://teratail.com/questions/127292
※コマンドでもできるらしい
https://docs.oracle.com/cd/E19226-01/821-1299/gharo/index.html
# grassfishのcliを実行
cd C:\<GrassFishのインストールフォルダ>\glassfish5\bin
asadmin
ふりかえり
- インジェクションする場合コンテナ管理になるので、GrassFishのコネクションプールを利用するらしい
- GrassFish + MySQLを利用する場合気を付ける。