Hibernate 6.0.0 の Jakarta Persistence のチュートリアルを動かす

[Hibernate Getting Started Guide Version 6.0.0.Final](https://docs.jboss.org/hibernate/orm/6.0/quickstart/html_single/) の [4. Tutorial Using the Java Persistence API (Jakarta Persistence)](https://docs.jboss.org/hibernate/orm/6.0/quickstart/html_single/#tutorial_jpa) がすんなり動かなかったので、動かすためのメモです。


# 資材

* [hibernate-tutorials.zip](https://docs.jboss.org/hibernate/orm/6.0/quickstart/html_single/hibernate-tutorials.zip)

基本的にサブディレクトリの entitymanager で作業します。


# 環境

[Hibernate ORM 6.0 series](https://hibernate.org/orm/releases/6.0/) の Compatibility の項目を見ると次のようになっています。

|  |  |
|-|-|
| [Java](https://www.oracle.com/technetwork/java/javase/downloads/index.html) | 11, 17 or 18 |
| [Jakarta Persistence](https://jakarta.ee/specifications/persistence/) | 3.1 and 3.0 |

最新の LTS バージョンである Java 17 と Jakarta Persistence 3.1 を使おうと思います。Maven の実行環境としては IntelliJ IDEA 2022.1 (英語のまま) を使います。

私は Jakarta Persistence の API も JPA だと思っていたのですが、仕様の文書名から "API" がなくなっていますので、正式には JPA とは言わないようです。


# 手順

## hibernate-tutorials.zip を展開する

IntelliJ の他のプロジェクトの隣 (IdeaProjects フォルダの直下) に展開しました。

## IntelliJ で開く

IntelliJ を起動して、"Welcome to IntelliJ IDEA" ダイアログの Open (ほかのプロジェクトが既に開かれていたら File > Open...) から hibernate-tutorials のフォルダを選び、Trust Project を押して開きます。読み込みが完了してから、左側の Project タブの entitymanager を完全に展開 (選択後、ダブル Shift > Fully Expand Tree Node)、右側の Maven タブから Hibernate JPA Tutorial を開くと以下のような状態になると思います。

![hibernate-tutorialsを開いたところ.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/782342/67951631-c7e6-5c13-f405-af0d9aba4903.png)

## Java のバージョンを指定する

Project タブで EntityManagerIllustrationTest をダブルクリックして開き、`testBasicUsage()` の ▶️ をクリックして実行を試みると、以下のエラーになってしまいました。

```
java: エラー: リリース・バージョン5はサポートされていません
```

entitymanager の pom.xml (以下、pom.xml) や hibernate-tutorials 直下の pom.xml (以下、../pom.xml) で Java のバージョンが指定されていないため、デフォルトが使われたようです。どちらを修正しても良いと思いますが、../pom.xml の `<properties>` と `</properties>` の間に以下の記述を加えます。

```xml
        <maven.compiler.source>17</maven.compiler.source>
        <maven.compiler.target>17</maven.compiler.target>
```

書き換えたら Ctrl-Shift-I で IntelliJ に設定を反映します。

[Setting the --release of the Java Compiler](https://maven.apache.org/plugins/maven-compiler-plugin/examples/set-compiler-release.html) のように `maven.compiler.release` を指定するのが本来かと思うのですが、そちらだと IntelliJ が認識してくれないようです。

再度 `testBasicUsage()` の ▶️ をクリックすると、今度は実行できました。

![実行できた.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/782342/748b5c09-0656-33dc-f21d-5d5477094df4.png)

## Hibernate 6.0.0.Final を使うようにする

Project の External Libraries のところを展開すると、javax.persistence-api:2.2 が使われてしまっています。

![JPA2.2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/782342/eebbf2e3-23aa-86d7-ab77-78381c01fc77.png)

pom.xml や ../pom.xml を見直してみると、hibernate-core が `6.0.0.Alpha6` のままです。hibernate-tutorials は Alpha6 が最新のようですので、hibernate-core のバージョンが指定されている2箇所だけを `6.0.0.Final` にします。

```xml
        <dependency>
            <groupId>org.hibernate</groupId>
            <artifactId>hibernate-core</artifactId>
            <version>6.0.0.Final</version>
        </dependency>
```

書き換えたら Ctrl-Shift-I で IntelliJ に設定を反映します。JPA 2.2 を使わなくなっているので、`Package not found: javax.persistence` や `Cannot resolve symbol 'Entity'` のようなエラーのためビルドが通らなくなります。

![ビルドが通らない.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/782342/d0517130-0389-fed9-397c-c980ca2ae3cb.png)

(上の図で External Libraries のところに javax.persistence-api:2.2 が残っていますが、entitymanager 以外は以前のままになっているためです。)

ビルド エラーの解消方法ですが、

```java
import javax.persistence.Entity
```

のように Java Persistence 時代の古いパッケージ名が指定されてしまっているので、以下のようにします。

```java
import jakarta.persistence.Entity
```

そこで、Project から entitymanager の src を選択して、Ctrl-Shift-R を押すと、Replace in Files の対象が Directory で src フォルダになっていると思いますので、置換元 `import javax.persistence`、`import jakarta.persistence` を指定して Replace All を押します。11 箇所が置換されます。

再度 `testBasicUsage()` の ▶️ をクリックすると、先ほどと同様に実行できるようになっています。

## プロパティ名を直す

ログに以下のような警告が何件か出力されるようになってしまったと思います。

```
WARN: HHH90000021: Encountered deprecated setting [javax.persistence.jdbc.user], use [jakarta.persistence.jdbc.user] instead
```

たしかに、[8.2.1.9. properties](https://jakarta.ee/specifications/persistence/3.1/jakarta-persistence-spec-3.1.html#a12384) を見るとプロパティ名が変更されています。

src/test/resources/META-INF/persistence.xml を開き、`javax.persistence` となっている箇所を `jakarta.persistence` に直します。

以下の箇所を覗いて警告がなくなります。

```
WARN: HHH90000021: Encountered deprecated setting [javax.persistence.lock.timeout], use [jakarta.persistence.lock.timeout] instead
```

残ってしまった警告は 6.0.0.Final の時点では [HHH-15189 Print deprecation warning for lock timeout only when a value is passed](https://github.com/hibernate/hibernate-orm/commit/dc42ec38ede9746bd667c61118e3d20f388c040a) が未修正のために発生していますので、ユーザーとしては修正版のリリースを待つほかありません。