19

リストが空の場合、次のエラーが発生します。

You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near ')'

以下は私の休止状態関連の方法です:

  @Override
    public List<SomeThing> findByIds(List<Integer> someIds) {
        return sessionFactory.getCurrentSession().createCriteria(SomeClass.class)
                .add(Restrictions.in("id", someIds))
                .list();
    }

このエラーを防ぐにはどうすればよいですか?

呼び出しを短絡して、次のような空のリストを返すことができることはわかっています。

if(someIds == null || someIds.size() == 0) {
  return new List<SomeThing>();
}

しかし、これを行うためのよりエレガントな方法はありますか?

4

3 に答える 3

17

Hibernateはこの問題を修正し、意味のあるメッセージを提供する必要があると思います。

空/nullリストをチェックするのはプロバイダー/ハイバネートの責任だと思います。

原因を想像することができます。それは、org.hibernate.loader.criteria.CriteriaQueryTranslatorなどのどこかに()のidのようなwhere句を構築しようとします。しかし、ここではリストが空であるため、例外がスローされます。しかし、彼らはすでに(そして例外/空のリストのために完了できなかった)でクエリを作成しました。

于 2012-10-22T06:21:55.700 に答える
17

番号。句に空のパラメーターを指定してクエリを実行するinと、失敗します (プレーン SQL を実行してこれを確認できます)。入力パラメーターが null/空の場合は、クエリを実行しない方がよいでしょう。

私がアドバイスできる唯一のことは、isEmpty()function と!= nullinifステートメントを使用し、次のように少し再構築することです。

@Override
public List<SomeThing> findByIds(List<Integer> someIds) {
   List<Something> result = null; //you may initialize with empty list
   if(someIds != null || !someIds.isEmpty() {
       result = sessionFactory.getCurrentSession().createCriteria(SomeClass.class)
            .add(Restrictions.in("id", someIds))
            .list();
   } 
   return result;
}
于 2012-10-22T03:24:00.667 に答える
2

(これは主に @Yogendra Singh の返信に基づいており、一般的に見られる複数のオプション引数の状況により採用しやすくするためにひねりを加えています)

Criteria API は、クエリをプログラムで作成できるようにすることを目的としています。この種の動的機能は、コードで処理されることが期待されます。

通常、これによりオプションの基準を作成します。

@Override
public List<SomeThing> findBySearchParams(SearchParam searchParam) {
   // create criteria with mandatory search criteria
   Criteria criteria = sessionFactory.getCurrentSession()
                           .createCriteria(SomeClass.class);
                           .add(Restriction("someField", searchParam.getSomeField()));


   // add "id" only if "someId" contains value
   if(searchParam.getSomeIds() != null && !searchParam.getSomeIds().empty()) {
       criteria.add(Restrictions.in("id", searchParam.getSomeIds()));
   } 

   // add "anotherField" only if "anOptionalField" is not null
   if(searchParam.getAnOptionalField() != null) {
       criteria.add(Restrictions.in("anotherField", searchParam.getAnOptionalField()));
   } 

   return criteria.list();
}

編集:

Hibernate は (まだ) そのためのよりエレガントな方法を提供していませんが、よりエレガントに見えるように自分で何かを書くことができます:

class SmartCriteriaBuilder {
  private Criteria criteria;
  SmartCriteriaBuilder (Criteria criteria) { this.criteria = criteria;}

  SmartCriteriaBuilder in(String field, Collection values) {
    if (!empty(values)) {
      this.criteria.add(Restrictions.in(field,values));
    }
  }
  // all other kind of restrictions ....

  Criteria toCriteria() {
    return this.criteria;
  }
}

次に、よりスマートに見える何かを行うことができます。

SmartCriteriaBuilder criteriaBuilder = 
    new SmartCriteriaBuilder(sessionFactory.getCurrentSession().createCriteria());

criteriaBuilder .in("someField", listPossiblyNullOrEmpty);


return criteriaBuilder .toCriteria().list();    
于 2012-10-22T04:29:55.723 に答える