質問: 特定のフィールド(カラム)だけを更新するメソッドをリポジトリに用意したいです。 * java - Update single field using spring data jpa - Stack Overflow * java - How to use hibernate @DynamicUpdate with spring data jpa? - Stack Overflow 上記あたりが、該当しそうな質問なのですが、2つ目に上げた質問への回答に > > I don't recommend using @Query unless you have a case where native JPA/Hibernate is insufficient, but if you have a use-case to update a target set of columns only, it is the best choice, and the most efficient. > > > とあります。今回私は、特定のフィールド(複数)をUpdateしたいので、上記英語に書いてあるベストチョイスなユースケースとして、`@Query`を選択しようと思っています。 --- そもそも、別の選択肢として`@DynamicUpdate`があるようですが、`@DynamicUpdate`が何かまだ理解していないので、もしかしたらそっちを先に質問したほうがいいのかもしれないです。 DynamicUpdate (Hibernate JavaDocs) > > For updating, should this entity use dynamic sql generation where only changed columns get referenced in the prepared sql statement? > > > Note, for re-attachment of detached entities this is not possible without select-before-update being enabled. > > > そもそもドキュメントの最後がクエッションマークになっており、疑問形のドキュメントとかで意味がわからない...(そもそも疑問形なのか?)(おそらく次のNoteから始まる文との関係性もなにもない) とか読む限り、癖が強そうで扱うのに手を焼きそうな印象...(といってこの程度はよくありそうな気もするが、といいつつ理解はあまりできていない) このまま `@DynamicUpdate` と `@Query` どっちがいいの??と書いていると、本質問の焦点がぶれそうなので、`@DynamicUpdate`への言及はここまでとします。 --- さて、クエリーを自分で書くとなると、SQLインジェクションについて注意することになってくると思います。 Spring Data JPA でのクエリー実装方法まとめ - Qiita によると `EntityManage`を使った方法として下記の方法があるとあります(私はまだ`EntityManage`を使ったことがありません) > > * ネイティブSQL > * JPQL > * CriteriaAPI > * 名前付きクエリー > * JPAプロバイダの機能を直接使用する > > > さらに > > 標準のメソッド以外のクエリーを作るには、Repositoryインターフェイスにクエリーメソッドを追加する。 > > クエリーメソッドの実装方法は以下の通り。 > > > * 命名規約に従ったメソッド名での自動実装 > * @Queryアノテーションでのクエリー指定 > * リポジトリ実装クラスでクエリーを実装する > * Specificationでの実装 > > > とあります。今回は本家StackOverflowの回答にあった通り`@Query`でいこうと思います。 さてこうして、上記のように様々な選択肢の中から`@Query`でいこう!と選択したわけですが(実際のところは本家の回答の一例がベストチョイスといってるのでそう決めたわけだが)、`@Query`には`SQL`が書けたり`JPQL`が書けたり、`Entityクラスに定義した名前付きクエリー`が書けたり様々あるようです。 ここから完全に推測なんですが、`ネイティブSQL`を書いた場合は、SQLインジェクションの心配はないのでしょうか? `JPQL`だと安全、いやいや `EntityManageクラス`こそ安全みたいなことはありますか?(おそらく`EntityManageクラス`にも`ネイティブSQL`が書けるようなので、`ネイティブSQL`が危険なのであれば、`EntityManage`でも`ネイティブSQL`を書いたらアウトな気がしますが...) まとめると、クエリーを自作する場合、SQLインジェクションについて考慮する必要があるのかどうか?ある場合、どれなら安全かとなります。
回答: `@Query`を利用した場合、一般的に割れているようなSQLインジェクション対策は行われた状態になっていると考えてよいかと思います。 www.ipa.go.jp サイトに対策方法についていくつかの記事があります。一例として、 * 別冊:「安全なSQLの呼び出し方」 を挙げると、この中では、対策のひとつとして「動的プレースホルダ」(3.2.2節)があると記載されています。 `@Query`を用いると、性質上、常にこの方式を利用することになります。 JPAネイティブクエリ/JPQLでSQLインジェクションが起こり得ることについては、次の記事で実証されていらっしゃいます: * JPQLインジェクションを確認してみました - Challenge Engineer Life ! (`@Query`を用いた場合、このように文字列連結でSQL/JPQLを構築できない) > > そもそもドキュメントの最後がクエッションマークになっており、疑問形のドキュメントとかで意味がわからない... > > > については`value`引数の`true`/`false`に掛かっているものだと思います。