hibernate criteria query - 子属性的属性

时间:2012-06-12 18:34:32

标签: hibernate hql criteria-api hibernate-criteria

我使用spring MVC 3.0和jqgrid插件。我正在为jqgrid构建搜索功能,它将json对象发送到服务器端。每当触发搜索时,我都创建了一个虚拟java类来解析jqgrid的json。一切都很顺利。

我正在动态创建我的条件查询,因为用户可以自由选择搜索条件(等于,不等于......等)。以下是jqgrid发送的json字符串的示例。

{
    "groupOp": "AND",
    "rules": [{
        "field": "company",
        "op": "cn",
        "data": "School"},
    {
        "field": "numberOfStudents",
        "op": "eq",
        "data": "2"}]
}​

这个os用作解析这个json的模板的java类

public class JsonJqgridSearchModel {

    public String groupOp;

    public ArrayList<JqgridSearchCriteria> rules;
}

注意名为JqgridSearchCriteria的类型,这是一个在我调用getRestriction()方法时随时返回一个限制的类。这是JqgridSearchCriteria

public class JqgridSearchCriteria {

    public String field;

    public String op;

    public String data;

    public SimpleExpression getRestriction(){
        if(op.equals("cn")){
            return Restrictions.like(field, data, MatchMode.ANYWHERE);
        }else if(op.equals("eq")){
            return Restrictions.eq(field, data);
        }else if(op.equals("ne")){
            return Restrictions.ne(field, data);
        }else if(op.equals("lt")){
            return Restrictions.lt(field, data);
        }else if(op.equals("le")){
            return Restrictions.le(field, data);
        }else if(op.equals("gt")){
            return Restrictions.gt(field, data);
        }else if(op.equals("ge")){
            return Restrictions.ge(field, data);
        }else{
            return null;
        }       
    }   
}

为了正确地传达我的问题,我不得不浪费一点时间。如果您观察到json字符串,您将看到为什么字段数据用于通过getRestriction()返回SimpleExpression。

这是我的 Object-A ,其中 Object-B 作为参考。我从网格中得到的是 Object-B.getName(),因此有一个JqgridSearchCriteria,其中 field = Object-B.getName(),数据是用户提供的名称。当这个运行时,我得到一个例外如下:

内部错误 抱歉,我们遇到了内部错误。 细节 无法通过tt.edu.sbcs.model.Organization.id的反射getter获取字段值 org.hibernate.property.DirectPropertyAccessor $ DirectGetter.get(DirectPropertyAccessor.java:62) org.hibernate.tuple.entity.AbstractEntityTuplizer.getIdentifier(AbstractEntityTuplizer.java:230) org.hibernate.persister.entity.AbstractEntityPersister.getIdentifier(AbstractEntityPersister.java:3852) org.hibernate.persister.entity.AbstractEntityPersister.isTransient(AbstractEntityPersister.java:3560) org.hibernate.engine.ForeignKeys.isTransient(ForeignKeys.java:204) org.hibernate.engine.ForeignKeys.getEntityIdentifierIfNotUnsaved(ForeignKeys.java:243) org.hibernate.type.EntityType.getIdentifier(EntityType.java:449) org.hibernate.type.ManyToOneType.nullSafeSet(ManyToOneType.java:142) org.hibernate.loader.Loader.bindPositionalParameters(Loader.java:1789) org.hibernate.loader.Loader.bindParameterValues(Loader.java:1760)                                。                                。                                

以下是这一切汇集在一起​​的片段。

Criteria criteria = session.createCriteria(CorporateRegistration.class); 
Iterator<JqgridSearchCriteria> iterator = jsonJqgridSearchModel.rules.iterator();
String operation = jsonJqgridSearchModel.groupOp;
if(operation.equals("AND")){
    Conjunction conjunction = Restrictions.conjunction();
    while(iterator.hasNext()){  
        conjunction.add(iterator.next().getRestriction());
    }           
    criteria.add(conjunction);
}//conjunctions are for AND operation
else{
    Disjunction disjunction = Restrictions.disjunction();
    while(iterator.hasNext()){  
        disjunction.add(iterator.next().getRestriction());
    }           
    criteria.add(disjunction);          
}//disjunctions are for OR operations       
    for(Object o: criteria.list()){
        corpRegList.add((CorporateRegistration)o);
    }

我也尝试过搜索数字,但是相关的值是一个字符串。 我是否使用标准的createAlias? 返回SimpleExpression时,是否可以指定名为data的属性的数据类型?

请指教。

2 个答案:

答案 0 :(得分:0)

关于搜索数字,我认为你的JqgridSearchCriteria类需要一个“type”属性。同样在UI中,您可能希望定制可用的运算符,以便用户无法为数值选择“包含”,例如。

在我们开发的类似系统中,我们使用['string','number','date']作为搜索值类型。用户可以选择用于搜索的每一列都有一个类型,以便我们可以使用javascript来显示适当的运算符列表。

这意味着您将在构建条件时知道正确地转换搜索条件值。它增加了应用程序的复杂性,但我没有看到任何替代方案。

答案 1 :(得分:0)

对于那些可能正在寻找答案的人,我使用了一个子标准。如果你有一个名为 A 的标准,对于这些类型的情况你可以说A.createCriteria(field).add(conjunction); 其中field是指拥有实体中的实际属性。以下是我创建的内容,以允许更具通用性的项目特定搜索逻辑。所以当你致电A.list()时,你很高兴。它有点长但很容易理解。

public class JqgridSearchCriteria {

    public String field;

    public String op;

    public String data;

    public String dataType;

    public String dataProperty;

    public SimpleExpression getSimpleExpression(String myField, Object o){
        if(op.equals("cn")){
            return Restrictions.like(myField, o.toString(), MatchMode.ANYWHERE);
        }else if(op.equals("eq")){
            return Restrictions.eq(myField, o);
        }else if(op.equals("ne")){
            return Restrictions.ne(myField, o);
        }else if(op.equals("lt")){
            return Restrictions.lt(myField, o);
        }else if(op.equals("le")){
            return Restrictions.le(myField, o);
        }else if(op.equals("gt")){
            return Restrictions.gt(myField, o);
        }else if(op.equals("ge")){
            return Restrictions.ge(myField, o);
        }else{
            return null;
        }       
    }   

    public void addMyRestriction(String groupOperation, Criteria criteria){
        Conjunction conjunction = Restrictions.conjunction();
        Disjunction disjunction = Restrictions.disjunction();
        if(groupOperation.equals("AND")){
            if(dataType.isEmpty()){
                conjunction.add(this.getSimpleExpression(field, data));
                criteria.add(conjunction);
            }else{
                if(dataType.equals("Calendar")){
                    try{
                        DateFormat formatter = new SimpleDateFormat("MMMM dd, yyyy");
                        Date date = (Date)formatter.parse(data);
                        Calendar cal = Calendar.getInstance();
                        cal.setTime(date);
                        conjunction.add(this.getSimpleExpression(field, cal));
                        criteria.add(conjunction);
                    }catch (ParseException e){
                        System.out.println("Exception :"+e);
                    }                   //used for calendar data types 
                }else if(dataType.equals("Long")){
                    Long myLong = Long.parseLong(data);
                    conjunction.add(this.getSimpleExpression(field, myLong));
                    criteria.add(conjunction);
                                        //used for Long data types
                }else if(dataType.equals("Integer")){
                    Integer myInt = Integer.parseInt(data);
                    conjunction.add(this.getSimpleExpression(field, myInt));
                    criteria.add(conjunction);
                                        //used for Integer data types
                }else{
                    conjunction.add(this.getSimpleExpression(dataProperty, data));
                    criteria.createCriteria(field).add(conjunction);
                }                       //used for custom or project specific data types
            }// AND operation used conjunctions
        }else{
            if(dataType.isEmpty()){
                disjunction.add(this.getSimpleExpression(field, data));
                criteria.add(disjunction);
            }else{

                if(dataType.equals("Calendar")){
                    try{
                        DateFormat formatter = new SimpleDateFormat("MMMM dd, yyyy");
                        Date date = (Date)formatter.parse(data);
                        Calendar cal = Calendar.getInstance();
                        cal.setTime(date);
                        disjunction.add(this.getSimpleExpression(field, cal));
                        criteria.add(disjunction);
                    }catch (ParseException e){
                        System.out.println("Exception :"+e);
                    } 
                }else if(dataType.equals("Long")){
                    Long myLong = Long.parseLong(data);
                    disjunction.add(this.getSimpleExpression(field, myLong));
                    criteria.add(disjunction);
                }else if(dataType.equals("Integer")){
                    Integer myInt = Integer.parseInt(data);
                    disjunction.add(this.getSimpleExpression(field, myInt));
                    criteria.add(disjunction);
                }else{
                    disjunction.add(this.getSimpleExpression(dataProperty, data));
                    criteria.createCriteria(field).add(disjunction);
                }
            }           
        }// OR operation used disjunctions
    }
}