如果我的列表为空,则会出现以下错误:
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 ')'
下面是我的hibernate相关方法:
@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>();
}
但有更优雅的方法吗?
答案 0 :(得分:13)
我想说Hibernate需要解决这个问题,并提供有意义的消息。
我认为它负责提供者/ hibernate检查空/空List。
可以想象原因,它试图构造where子句,类似id in(),org.hibernate.loader.criteria.CriteriaQueryTranslator或类似的东西。但是因为这里List是空的,它会抛出一个例外。但是他们已经创建了查询(并且由于异常/空List而无法完成。
答案 1 :(得分:12)
NO。如果使用in
子句的空参数执行查询,它将失败(您可以通过运行纯SQL来验证这一点)。如果输入参数为空/空,最好不要执行查询。
我唯一可以建议的是在isEmpty()
声明中使用!= null
函数和if
并进行少量重组:
@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;
}
答案 2 :(得分: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();