透過集合值輸入參數來驗證 IN 表示式語法

IN 表示式的「Java 持續性 API (JPA)」規格定義的集合值輸入參數沒有用括弧括住。OpenJPA 容許括弧存在,但當您用來呼叫 Query.setParameter 方法的集合物件對應於以括弧括住的 IN 集合值輸入參數時,EclipseLink 會擲出異常狀況。

此規則會偵測包含「Java 持續性查詢語言 (JPQL)」陳述式(內含以括弧括住單一參數的 IN 表示式)的字串。 由於查詢字串及 setParameter 的對應呼叫可能分屬不同類別,因此該規則無法保證此參數是集合。 如果此參數是集合類型,請移除查詢字串的括弧。 請注意,括弧適用於文字或單值輸入參數,因此請注意您移除的內容。

透過移除含有集合值輸入參數的 IN 表示式的括弧,而解決此問題。

例如,OpenJPA 容許下列查詢字串中有括弧,但當您呼叫 setParameter 並嘗試將 ids 設定為屬於集合的值時,EclipseLink 會擲出異常狀況。

  List<String> idList = getIdsToQuery();
  Query query = em.createQuery("SELECT p FROM Person p WHERE p.id IN (:ids)");
  query.setParameter("ids", idList);
  
  final String ENTITY_NAME = "Person";
  final String PRIMARY_KEY = "id";
  List<String> idList2 = getIdsToQuery();
  Query query = em.createQuery("SELECT p FROM " + ENTITY_NAME + " p " +" WHERE p." + PRIMARY_KEY + " IN (:ids)");
  query.setParameter("ids", idList2);

若要解決此問題,當 ids 代表集合時,請移除括弧。

  List<String> idList = getIdsToQuery();
  Query query = em.createQuery("SELECT p FROM Person p WHERE p.id IN :ids");
  query.setParameter("ids", idList);
  
  final String ENTITY_NAME = "Person";
  final String PRIMARY_KEY = "id";
  List<String> idList2 = getIdsToQuery();
  Query query = em.createQuery("SELECT p FROM " + ENTITY_NAME + " p " +" WHERE p." + PRIMARY_KEY + " IN :ids");
  query.setParameter("ids", idList2);

下面顯示將要標示但不應變更的範例,因為 id 是單值參數。


  String idMatch = getIdToQuery();
  Query query = em.createQuery(SELECT p FROM Person p WHERE p.id IN (:id));
  query.setParameter("id", idMatch);
  

如需此問題以及其他 OpenJPA 至 EclipseLink 移轉問題的相關資訊,請參閱: