java 如果列表为空,则休眠限制会导致错误

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/13004142/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-31 11:06:22  来源:igfitidea点击:

Hibernate restriction in causes an error if the list is empty

javahibernate

提问by Blankman

If my list is empty, I get the following error:

如果我的列表为空,则会出现以下错误:

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 ')'

Below is my hibernate related method:

以下是我的休眠相关方法:

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

What should I do to guard against this error?

我应该怎么做才能防止这个错误?

I know I could short-circuit the call and return an empty list like:

我知道我可以使呼叫短路并返回一个空列表,例如:

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

But is there a more elegant way to do this?

但是有没有更优雅的方法来做到这一点?

回答by Yogendra Singh

NO.If you execute the query with empty parameters for inclause, it will fail (you may verify this by running plain SQL). Better not to execute the query if the input param is null/empty.

不。如果您使用空参数 forin子句执行查询,它将失败(您可以通过运行普通 SQL 来验证这一点)。如果输入参数为空/空,最好不要执行查询。

Only thing I can advice is to use isEmpty()function and != nullin ifstatement and little restructuring as:

只有我的建议就是要使用isEmpty()的功能和!= nullif声明和小结构调整:

@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;
}

回答by Maddy

I would say Hibernate needs to fix this issue, and give meaningful message.

我会说 Hibernate 需要解决这个问题,并给出有意义的信息。

I think its responsibility of the provider/hibernate to check for the empty/null List.

我认为提供者/休眠检查空/空列表的责任。

One can imagine the cause, it tries to construct where clause, something like id in (), somewhere in org.hibernate.loader.criteria.CriteriaQueryTranslator or similar..But because here the List is empty, it would be throwing an exception. But they already created query with ( and could not complete because of exception/empty List.

可以想象原因,它试图构造 where 子句,比如 id in (),在 org.hibernate.loader.criteria.CriteriaQueryTranslator 或类似的某处。但因为这里的 List 是空的,它会抛出异常。但是他们已经用 ( 创建了查询并且由于异常/空列表而无法完成。

回答by Adrian Shum

(This is mostly base on @Yogendra Singh's reply, with a twist to make it more adoptable to commonly-seen situation of multiple optional argument)

(这主要基于@Yogendra Singh 的回复,稍加改动,使其更适用于常见的多个可选参数的情况)

Criteria API aims to let you compose your query programmatically. Such kind of dynamic feature is expected to be handled in your code.

Criteria API 旨在让您以编程方式编写查询。此类动态功能应在您的代码中处理。

Normally we make optional criteria by this:

通常我们通过以下方式制定可选标准:

@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();
}


Edit:

编辑:

Although Hibernate does not (yet) provide a more elegant way for that, you can write something yourself to make it looks more elegant:

尽管 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;
  }
}

Then you can do something looks smarter:

然后你可以做一些看起来更聪明的事情:

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

criteriaBuilder .in("someField", listPossiblyNullOrEmpty);


return criteriaBuilder .toCriteria().list();