- 部屋(Room)テーブルと備品(Equipment)テーブルがあり、それぞれ1対多のリレーションがあるとする。


- JPQLでの結合をしてみる。
package com.example.demo.repository;
import java.util.List;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;
import com.example.demo.entity.Room;
public interface RoomRepository extends JpaRepository<Room, Integer> {
@Query("SELECT r FROM Room r LEFT OUTER JOIN r.equipments")
List<Room> find();
}
独特な構文だが、この書き方の場合、RoomテーブルをSELECTした後に、Equipmentテーブルを1件ずつ取得する、いわゆるN+1問題が発生する。
①Roomテーブルのselect
select
r1_0.room_id,
r1_0.invalid,
r1_0.room_name
from
room r1_0 left join equipment e1_0 on r1_0.room_id=e1_0.room_id
②①で取得したRoomテーブルのレコードのうち、
Equipmentテーブルに紐づくレコードがある場合、都度selectを行う。
select
e1_0.room_id,
e1_0.equipment_id,
e1_0.equipment_name,
e1_0.invalid
from
equipment e1_0
where
e1_0.room_id=?
binding parameter [1] as [INTEGER] - [1]
select
e1_0.room_id,
e1_0.equipment_id,
e1_0.equipment_name,
e1_0.invalid
from
equipment e1_0
where
e1_0.room_id=?
binding parameter [1] as [INTEGER] - [2]
select
e1_0.room_id,
e1_0.equipment_id,
e1_0.equipment_name,
e1_0.invalid
from
equipment e1_0
where
e1_0.room_id=?
binding parameter [1] as [INTEGER] - [3k]
- これを防ぐにはJOIN FETCHを行う。
package com.example.demo.repository;
import java.util.List;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;
import com.example.demo.entity.Room;
public interface RoomRepository extends JpaRepository<Room, Integer> {
@Query("SELECT r FROM Room r LEFT OUTER JOIN FETCH r.equipments")
List<Room> find();
}
- 実行結果を見ると一度のクエリで結合情報を取得できていた。
select
r1_0.room_id,
e1_0.room_id,
e1_0.equipment_id,
e1_0.equipment_name,
e1_0.invalid,
r1_0.invalid,
r1_0.room_name
from
room r1_0 left join equipment e1_0
on r1_0.room_id=e1_0.room_id
- よほどの理由がない限り、JPQLで結合を行うときはFETCHをつけること。
サーモス 水筒 調乳用ステンレスボトル 350ml ミッフィー グレー JPA-350B GY
¥4,291 (2025年8月26日 12:29 GMT +09:00 時点 - 詳細はこちら価格および発送可能時期は表示された日付/時刻の時点のものであり、変更される場合があります。本商品の購入においては、購入の時点で当該の Amazon サイトに表示されている価格および発送可能時期の情報が適用されます。)調乳用ステンレスボトルが洗いやすく、持ち運びやすくリニューアル 本体サイズ(約):幅6.5×奥行き7.5×高さ18cm、本体重量(約):200g、容量:350ml 保温効力:64℃以上(6時間)71℃以上(4時間)/保冷効力:11℃以下(6時間) 生産国:中国 素材・材質:内びん:ステンレス鋼 / 胴部:ステンレス鋼(アクリル樹脂塗装)/ フタ・せん本体・注ぎ口(飲み口):ポリプロピレン / フタパッキン・せんパッキン:シリコーンゴム
コメント