1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

関連エンティティがあるときのJPQLの書き方

Posted at

環境

Spring boot

参考にしたサイト

Spring DATA JPAでデータ検索
JPQLの内部テーブル結合を試してみる

エラーメッセージ

MySQL server version for the right syntax to use near '' at line 1

もうこし長かったけど、構文エラーがあるよってエラー。

原因

JPQLの書き方が間違っていた!というか、MySQLのNativeQueryとはちょっと書き方がちがうんだなぁ~くらいの認識でしたけど、結構違う感じでしたね。

特に@OneToOneとかの関連エンティティがある場合の扱い方が間違っていました。

外部キーで結合するので、LEFT JOINとか書いていたけど、それが原因でした。

application.propertiesに次のように書いて、SQLを参考にしました。コンソールに大量に表示されるようになります。

application.properties
spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.MySQL5Dialect
spring.jpa.show-sql=true

けど、MySQLのSQL文とはなんかが違うみたいですね。

Hibernateってなに?

wikiによると

Java のためのオブジェクト関係マッピング (ORM) ライブラリであり、オブジェクト指向のドメインモデルを関係データベースにマッピングするためのフレームワークを提供する。

初心者には難しいですけど、多分の解釈でいうと、
データベースから取得してきたデータを、オブジェクトとかインスタンスのフィールドに代入して、以降はオブジェクトとして扱えるようにするためにHibernateっていうのがよしなにやってくれる

って認識で良さそうです。

PHPの学習をしているときには、

  1. DB接続
  2. レコード取得
  3. カラムを取得
  4. 配列に格納
  5. DB切断

って言う流れをそのまま書いてましたね。オブジェクトとかクラスをまだ知らないときです。

Javaをやりだして、早速クラスを勉強して、便利さもわかってきたところでなんとデーブルをそのままクラスと対応させることができるということもできることを理解しだしたのが最近です。

JPQLってなに?

JPAでDB(正確にはエンティティ)からデータを取得するSQLをJPQLと言います。

RepositoryでJPAが出てきてたな。これでデータベースから取得してクラスに格納できるようになるんだなと、なんとなく理解。

Repositoryでも@Queryアノテーションを付けてfindBy~みたいなメソッドを定義したことあったけど、なんのこっちゃわかっていませんでした。

でも今日わかったことが。

// 普通のSQL文を自分で書く
@Query(value="select * from なんちゃら~", nativeQuery = true)
// これがJPQLで、テーブルと紐付けたエンティティでSQL文を書ける的な
@Query("select エイリアス from オブジェクト エイリアス ~")

確かにわかりやすい記述ができるから便利だな~

エンティティの中に別のエンティティがあったらどうするの?

spring.jpa.show-sql=trueとしていると、
jpaで発行されたSQLがコンソールに出力されるので、それを見ると、結合しているテーブルがある場合はleft outer joinって書いてました。

ちょっと複雑な条件の場合は生のSQL文を書いて、結合の部分はleft outer joinって書けばいいんだなとあいまいに考えていましたが、ちゃいましたね。

@OneToOne@OneToManyなどのアノテーションで関連を記述していたら、そのエンティティを含むオブジェクトをデータベースから取得する際にjpaが勝手に中のエンティティのデータも持ってきてくれる。

イメージ

Book.java

public class Book {
private Integer id;
private String name;

@OneToOne( fetch = FetchType.EAGER ,cascade = CascadeType.ALL)
@JoinColumn(name="buyer_id")
private Buyer buyer;

}

Buyer.java
public class Buyer {
private name;
private address;
}

image.png

こんなイメージの関係性で、この場合は、

@Query("select b from Book b")

とするだけで、Buyerもちゃんと取ってきてくれる。

Joinとか書いてたら永遠に構文エラーが発生する

@Query("select b from Book b JOIN Buyer")

って書いてたら永遠に構文エラーになります。

しかもどこがおかしいっていうメッセージも、なんか場所がちがうんですよね。

near '' at line 1
``

ってどこ??`''`の中におかしいところがあるよってメッセージだけど、なんかちゃんと教えてくれませんでした。


### 結論!

JPQLとSQLは違うよっていう明確な、強い意志と理念が必要!!



1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?