2012-10-22 39 views
10

如果我的列表是空的,我得到以下錯誤:休眠限制的錯誤,如果列表爲空

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

但有一個更優雅的方式來做到這一點?

回答

11

NO。如果您使用in子句的空參數執行查詢,它將失敗(您可以通過運行普通SQL來驗證)。如果輸入參數爲空/空,最好不要執行查詢。

只有我將建議就是用isEmpty()功能和if聲明!= null和小調整爲:

@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

(這主要是對@Yogendra辛格的答覆的基礎上,與一捻,使其更可採用到多選可選參數的常見情況)

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();  
11

我會說Hibernate需要解決這個問題,並給出有意義的消息。

我認爲它的責任提供者/休眠檢查空/空列表。

可以想象的原因,它試圖構造where子句,像id(),org.hibernate.loader.criteria.CriteriaQueryTranslator或類似的地方..但因爲這裏列表是空的,它會是拋出異常。但他們已經創建了查詢(並且由於異常/空列表而無法完成)。