web-dev-qa-db-ja.com

SpringデータのJPAクエリでListパラメーターがnullであることを確認する

Spring Bootアプリケーションがあり、Spring Data JPAを使用してMySQLデータベースをクエリします。

いくつかのパラメーターでフィルターされたコースのリストを取得する必要があります。

通常、param IS NULL or (/*do something with param*/)という構文を使用して、nullのパラメーターを無視するようにします。

単純なデータ型では問題はありませんが、オブジェクトのリストに関しては、NULLの値を確認する方法がわかりません。次のクエリで_?3_パラメータがNULLかどうかを確認するにはどうすればよいですか?

_@Query("SELECT DISTINCT c FROM Course c\n" +
       "WHERE c.courseDate < CURRENT_TIME\n" +
       "AND (?1 IS NULL OR (c.id NOT IN (3, 4, 5)))\n" +
       "AND (?2 IS NULL OR (c.title LIKE ?2 OR c.description LIKE ?2))\n" +
       "AND ((?3) IS NULL OR (c.category IN ?3)) ")
List<Course> getCoursesFiltered(Long courseId, String filter, List<Category> categories);
_

エラーは:

resultSetを抽出できませんでした。 SQL [n/a];ネストされた例外はorg.hibernate.exception.DataException:ResultSetを抽出できませんでした[SQL:1241、21000]

そして私が見ることができるスタックトレースで:

原因:Java.sql.SQLException:オペランドには1つの列が含まれている必要があります

リストに3つの要素が含まれている場合、実際に生成されるクエリは... AND ((?3, ?4, ?5) IS NULL OR (c.category IN (?3, ?4, ?5)))になります。ただし、_IS NULL_を複数の要素に適用することはできません(リストに要素が1つしか含まれていない場合、クエリは正常に機能します)。

size(?3) < 1length(?3) < 1、_(?3) IS EMPTY_などを試しましたが、まだうまくいきません。

5
Yann39

これは厳密にあなたの質問に答えるものではありませんが、1つの簡単な解決策は、クエリを呼び出す前にリストをチェックし、ダミー値を持つリストにデフォルト設定する別のメソッドをリポジトリに含めることです。何かのようなもの:

@Query("SELECT DISTINCT c FROM Course c\n" +
       "WHERE c.courseDate < CURRENT_TIME\n" +
       "AND (?1 IS NULL OR (c.id NOT IN (3, 4, 5)))\n" +
       "AND (?2 IS NULL OR (c.title LIKE ?2 OR c.description LIKE ?2))\n" +
       "AND ('DUMMYVALUE' IN ?3 OR (c.category IN ?3)) ")
// make this private to keep it safe
private List<Course> getCoursesFiltered(Long courseId, String filter, List<Category> categories);

// public helper method to put a dummy value in the list that you can check for
public List<Course> getNullableCoursesFiltered(Long courseId, String filter, List<Category> categories) {
    if(categories == null) {
        categories = Arrays.asList("DUMMYVALUE");
    }
    return getCoursesFiltered(courseId, filter, categories);
}
1
Matt