2011-09-23 156 views
1

我有一個Java類,它有一些字段用@SearchCriteria(criteria = "class1.class2.field")註解。裏面標註criteria參數用於與類本場應設置爲休眠的標準,它的意思是說,如果現場標記,例如:使用子準則創建動態休眠標準查詢

@SearchCriteria(criteria = "class1.class2.field") 
private String value; 

我要動態地創建一種與外表休眠標準像

DetachedCriteria hibernateCriteria = forClass(Class.class); 
hibernateCriteria.createCriteria("class1").createCriteria("class2").add(eq("field", value)); 

問題是我不能設置另一個標準來添加,這意味着我應該檢查註釋criteria選項。

 switch (annotationCriteria.length - 1) { 
case 0:    
hibernateCriteria.add(isNull(annotationCriteria[0]));    
case 1: 
hibernateCriteria.createCriteria(annotationCriteria[0]).add(    Restrictions.isNull(annotationCriteria[annotationCriteria.length - 1])); 
case 2: hibernateCriteria.createCriteria(annotationCriteria[0]).createCriteria(annotationCriteria[1]).add(    Restrictions.isNull(annotationCriteria[annotationCriteria.length - 1])); 
    } 

我想刪除這個「swith」。有可能已經添加了標準,我現在不用,例如通過「名稱」,並添加新的子標準。

回答

1

我對這個問題找到了更好的解決方案。所有的 首先創建一些searchCriteria類,例如:

public class SearchCriteria { 

    @SearchCriteria(path = "someclass.someclass.id") 
    private Integer someId; 

    public Integer getSomeId() { 
     return someId; 
    } 

    public void setSomeId(Integer someId) { 
     this.someId= someId; 
    } 
} 

和自定義註釋:

@Target(value = { ElementType.FIELD }) 
@Retention(RUNTIME) 
public @interface SearchCriteria { 
    String path() default ""; 

    boolean optional() default true; 
} 

而在DAO類:

@Override 
    public Collection<SomeClass> find(SearchCriteria criteria) { 
     DetachedCriteria hibernateCriteria = forClass(SomeClass.class); 

     for (Field field : criteria.getClass().getDeclaredFields()) { 
      Annotation annotation = field.getAnnotation(SearchCriteria.class); 

      if (annotation == null) { 
       continue; 
      } 

      List<String> elements = Arrays.asList(StringUtils.split(((SearchCriteria) annotation).path(), ".")); 

      field.setAccessible(true); 
      Object fieldValue = null; 
      try { 
       fieldValue = field.get(criteria); 
      } catch (IllegalArgumentException e) { 
       LOG.error("while trying to get private field value of entity " + SearchCriteria.class, e); 
      } catch (IllegalAccessException e) { 
       LOG.error("while trying to get private field value of entity " + SearchCriteria.class, e); 
      } 

      for (String element : elements) { 
       if (elements.indexOf(element) == elements.size() - 1) { 
        hibernateCriteria = hibernateCriteria.add(eq(element, fieldValue)); 
       } else { 
        hibernateCriteria = hibernateCriteria.createCriteria(element); 
       } 
      } 
     } 

     return getHibernateTemplate().findByCriteria(hibernateCriteria); 
    } 
1

不,這是不可能的。 Detached Criteria API沒有 - 好或壞 - 允許發現,所以你不能問它「現有」的標準。

但是,您可以做的是通過關聯路徑維護您自己的嵌套標準地圖。在僞代碼中:

Map<String, DetachedCriteria> criteriaMap = ...; 

for () { // loop over annotation criteria's "elements" 
    DetachedCriteria existing = criteriaMap.get(fullPath); 
    if (existing==null) { 
     existing = parentCriteria.createCriteria(pathElement); 
     criteriaMap.put(fullPath, existing); 
    } 
    existing.add(whateverCondition); 
}