0

jqgridプラグインでSpringMVC3.0を使用しています。サーバー側にjsonオブジェクトを送信するjqgridの検索機能を構築しています。検索がトリガーされるたびにjqgridのjsonを解析するためのダミーのJavaクラスを作成しました。この時点まではすべて順調です。

ユーザーが検索条件(等しい、等しくないなど)を自由に選択できるため、基準クエリを動的に作成しています。これは、jqgridによって送信されたjson文字列の例です。

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

これは、このJSONを解析するためのテンプレートとして使用されるJavaクラスです。

public class JsonJqgridSearchModel {

    public String groupOp;

    public ArrayList<JqgridSearchCriteria> rules;
}

JqgridSearchCriteriaというタイプに注意してください。これは、getRestriction()メソッドを呼び出すたびに1つの制限を返すだけのクラスです。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-Bを参照として持つObject-Aを持っています。グリッドから取得しているのはObject-B.getName()であるため、field = Object-B.getName()があり、データはユーザーが指定した名前です。これを実行すると、次のような例外が発生します。JqgridSearchCriteria

Internal Error
Sorry, we encountered an internal error.
Details
could not get a field value by reflection getter of tt.edu.sbcs.model.Organization.id
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というプロパティのデータ型を指定できますか?

4

2 に答える 2

0

数値の検索に関しては、JqgridSearchCriteriaクラスに「type」プロパティが必要になると思います。また、UIでは、たとえば、ユーザーが数値に「含む」を選択できないように、使用可能な演算子を調整する必要があります。

開発したばかりの同様のシステムでは、検索値の型に['string'、'number'、'date']を使用しました。ユーザーが検索用に選択できるすべての列にはタイプがあるため、JavaScriptを使用して適切な演算子のリストを表示できます。

これは、基準を作成するときに検索基準値を適切にキャストすることを知っていることを意味します。アプリケーションが複雑になりますが、他に方法はありません。

于 2012-06-13T14:26:21.400 に答える
0

答えを探しているかもしれない人のために、私はサブ基準を使用しました。つまり、AA.createCriteria(field).add(conjunction);と呼ばれる基準がある場合、これらのタイプの状況 では、フィールドが所有エンティティの実際のプロパティを参照していると言えます。これは、プロジェクト固有のより一般的な検索ロジックを可能にするために作成したものです。だからあなたが電話するときあなたは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
    }
}
于 2012-06-22T17:21:27.563 に答える