2011-09-23 153 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); 
}