1
/
5

JPAの仕様を洗っていく【株式会社ライトコード】

※弊社エンジニアの記事になります。

前提

話がややこしくなるので事前に説明しておくと、Javaを介したDB操作をする上で JPA と Spring Data JPA という似ている2つのワードが出てきます。簡単に違いを説明すると JPA はJavaオブジェクトとDBカラムのマッピングを仕様として定義したものです。その仕様(JPA)に則ったライブラリを提供しているのが Spring Data JPA になります。JPAそのままでもDBとやり取りすることは可能ですが、仕組みがかなりややこしく学習コストが高いです。そのため簡易的にJPAを使用できるようにしてくれるSpring Data JPAが用意されています。今回の記事ではJPAをメインに解説を進めつつ、Spring Data JPAにも触れていきたいと思います。

仕様確認に至った経緯

ここ数ヶ月で Spring Data JPA に触れる機会が増えたにも関わらず、動作の詳細について把握していなかったことが原因で実装が手間取ったことがありました。

具体的には下記のようにDBを更新する場面で、saveメソッドの実行時に裏でUPDATEのSQLが走る想定をしていたのですが、実際には別のタイミングでSQLは実行されていました。(詳細については後述)

try {
  userRepository.save(userEntity);
} catch (ObjectOptimisticLockingFailureException e) {
  // 例外をスロー
}

そのため Spring Data JPA ないしはその大元にある JPA について根っこから概要を押さえる必要があると感じ、そのアウトプットも兼ねて本記事の投稿に至りました。

JPA

まずJPAの重要な要素として Entity と Entity Manager があります。

EntityはDBのテーブルと1対1で対応するJavaオブジェクトです。コード上では @Entity がついているクラスが該当します。

Entity ManagerはEntityのライフサイクル管理を PersistenceContext という領域で行います。その際に使用することができるEntity Managerのメソッドとして主に以下のものがあります。

persist

引数にエンティティを渡すとそのエンティティをPersistenceContextに格納し、管理状態として永続化する。(INSERT)

find

管理状態のエンティティの中から、引数で渡したIDに紐づくエンティティを返却する。(SELECT)

merge

引数で指定したエンティティの状態をPersistenceContext内にあるエンティティに反映する。(UPDATE)remove​

引数で指定したエンティティの状態を削除状態にする。(DELETE)

flush

上記メソッドで行ったエンティティへの変更をDBに反映する。このメソッドを実行して初めてPersistenceContext内のエンティティとDBの状態が同期される。

detach

PersistenceContextで管理しているエンティティを削除し管理対象から外します。removeと似ていますがライフサイクル的には削除状態にはならず "分離状態" として扱われます。※分離状態のエンティティに対する変更はDBに反映されません(管理対象外のため)

contain

引数で指定したエンティティがPersistenceContext内に存在するかチェックする。

refresh

管理状態のエンティティにDBの情報を反映させる。 ※管理状態でないエンティティを指定した場合例外が発生します。

clear

PersistenceContextをクリアし、全ての管理状態のエンティティを分離状態にする。

例としてUserテーブルにレコードをINSERTする場合のコードを用意しました。

// PersistenceContextとEntityManagerを紐づけ
@PersistenceContext(unitName="ExampleUnit")
private EntityManager em;
 
public void insertUser() {
  // UserEntity取得
  var userEntity = new UserEntity();
 
  // 名前を変更
  userEntity.setName("佐藤");
 
  // PersistenceContextでの管理対象に指定
  this.em.persist(userEntity);
 
  // 変更内容をコミット ※JPAはコミット時にEntityへの変更をDBに反映する
  this.em.getTransaction().commit();
}

※今回あえてcommitメソッドを書いていますがJPAでは自動コミット機能があり、insertUser()の処理が全て終了した時点で勝手にコミットしてくれるため本来は記載不要です。

例として今回はINSERTのコードを記載しましたが、UPDATEしたい場合はnewの箇所をfind()によるエンティティ取得に置き換えるだけで実現できます。

JPAでは上記のように様々なメソッドを使用しエンティティのライフサイクル管理を行いDBを操作します。しかし、単純な参照や更新ならともかく複雑なDB操作を行いたい場合にややこしくなります。そのためJPAをそのまま使用するのではなく、簡易的に使用することができる Spring Data JPA の使用を検討する方が多いと思います。(検討する方が多いのはあくまでJPAを使う前提がある人の話です。そもそもJPAの使用自体避けられている印象、、、)

記事の続きは下のリンクをクリック!

https://rightcode.co.jp/blog/information-technology/jpa

【2024年卒】新卒採用エントリー開始しました!

特設ページはこちら:https://rightcode.co.jp/recruit/entry-2024

※終了致しました。

インターン募集!未経験ok、チャレンジ精神ある方求む

メディア運営:https://rightcode.co.jp/recruit/intern-media

社長と一杯飲みながらお話しませんか?(転職者向け)

特設ページはこちら: https://rightcode.co.jp/gohan-sake-president-talk

もっとワクワクしたいあなたへ

現在、ライトコードでは「WEBエンジニア」「スマホアプリエンジニア」「ゲームエンジニア」、「デザイナー」「WEBディレクター」「エンジニアリングマネージャー」「営業」などを積極採用中です!

有名WEBサービスやアプリの受託開発などの企画、開発案件が目白押しの状況です。

  • もっと大きなことに挑戦したい!
  • エンジニアとしてもっと成長したい!
  • モダンな技術に触れたい!

現状に満足していない方は、まずは、エンジニアとしても第一線を走り続ける弊社代表と気軽にお話してみませんか?

ネット上では、ちょっとユルそうな会社に感じると思いますが(笑)、
実は技術力に定評があり、沢山の実績を残している会社ということをお伝えしたいと思っております。

  • ライトコードの魅力を知っていただきたい!
  • 社風や文化なども知っていただきたい!
  • 技術に対して熱意のある方に入社していただきたい!

一度、【Wantedly内の弊社ページ】や【コーポレートサイト】をのぞいてみてください。

【コーポレートサイト】https://rightcode.co.jp/

【採用募集】https://rightcode.co.jp/recruit(こちらからの応募がスムーズ)

【wantedlyぺージ】https://www.wantedly.com/companies/rightcode

株式会社ライトコードからお誘い
この話題に共感したら、メンバーと話してみませんか?
株式会社ライトコードでは一緒に働く仲間を募集しています

今週のランキング

調枝 寛之さんにいいねを伝えよう
調枝 寛之さんや会社があなたに興味を持つかも