2016-09-12 20 views
0

バージョン1.3からバージョン2.5にアップグレードしようとしています。 Enumのフィールドの1つを持つドメインクラスがあります。コントローラでは、domainObj.validate()を実行すると、常にfalseが返されます。検証エラーです -Grails 2.5:domainObj.properties = paramsの場合、domainObj.validate()メソッドがfalseを返します

grails.validation.ValidationErrors:1エラー フィールド 'typeEnum'のオブジェクト 'Parameter'のフィールドエラー:拒否された値[0]です。コード[com.TypeEnum.typeMismatch.error、com.TypeEnum.typeMismatch、com.TypeEnum.typeMismatch.error、com.TypeEnum.typeMismatch、typeMismatch.com.TypeEnum、typeMismatch.pspValueTypeEnum、typeMismatch.com.TypeEnum、typeMismatch];引数[typeEnum];デフォルトのメッセージ[いいえ列挙型定数com.TypeEnum.0]

EDITさらなる分析では、私は問題が列挙型ではないことがわかったが、parameterObj.propertiesの=のparamsを実行したときに、parameterObj.validate( )はfalseを返します。 Grailsの2.5と私のコードで

parameterObj.validate() //returns true 

parameterObj.properties = params 
// code to convert String from params to Enum object and assign it to parameterObj 
parameterObj.enumField = MyEnumClass.getEnumByName(params.enumNameValue) 
parameterObj.validate() //This always return false 

注:検証の両方の上記の場合において()、parameterObjのフィールドの値が正確に同じである

は、プロパティを使用して任意の変更がありますGrails 2.5のドメインクラスで?

+0

の年のためにうまく働いた、あなたが失敗したフィールドのドメインクラスのプロパティ定義を提供してくださいすることができ、 paramsのキー/値のプリントアウトも可能ですか? エラーが依然として投稿されたValidationErrorの場合、grailsは明らかに文字列値をTypeEnumに変換する必要があるため、文字列 "0"をTypeEnumフィールドに書き込もうとします。 – norganos

+0

はい、Grailsは "0 TypeEnumに渡します。したがって、検証する前に、 "0"をenumオブジェクトに変換して、それをドメインオブジェクトに割り当てています。より具体的に上記のコードを編集しました – nshweta

答えて

0

かなりの間苦労した後、私はGrails 2.5でこの動作の解決策を見つけることができました。ここに私の解決と観察があります。参考のために、再びのための私の問題のコードを貼り付け:

parameterObj.validate() //returns true 

parameterObj.properties = params 
// code to convert String from params to Enum object and assign it to parameterObj 
parameterObj.enumField = MyEnumClass.getEnumByName(params.enumNameValue) 
parameterObj.validate() //This always return false 
  1. は(私の例ではenumFieldのような)フィールドは、次に列挙文字列値は、ドメインオブジェクト(parameterObj)に渡されると予想される列挙型とされていない場合enumオブジェクト。 domainObjに

    enum TypeEnum { 
        STRING(0, "String"), NUMBER(1, "Number"), TIME(2, "Time") 
        ... 
        } 
    
次いで

値を送信する 例えば、私の列挙型である場合は "STRING" または "NUMBER" など

  • であります私の場合、プロパティにparamsを代入した後に "STRING"でenumFieldを更新すると、validateはfalseを返します。例えば、

    parameterObj.properties = params 
    parameterObj.enumField = "STRING" 
    parameterObj.validate() // returns FALSE 
    

    は、だから私は、validate()メソッドにより、正しい結果を得るためにparameterObj.propertiesの= paramsはを行う前のparamsにenumFieldを更新する必要がありました。したがって、このシーケンスの下のコードはうまく動作します。

    params.enumField = "STRING" 
    parameterObj.properties = params 
    parameterObj.validate() // returns True as expected 
    

    これは、Grailsの以前のバージョンとそうではありませんでした私のアプリケーションは、Grailsのバージョン1.3.3

  • 0

    ビューを変更すると、列挙型の名前()がパラメータ値として送信され、データバインディングがそのまま出力されます。

    少なくとも私はいつも列挙型を使用しています。名前との結合

    列挙型データ()

    <g:select name="typeEnum" from="${TypeEnum.values()}" value="${obj.typeEnum}"/> 
    

    Grailsは、値と表示されたテキストとして.toString()などの各列挙値の.nameの()を使用します。

    <select name="typeEnum"> 
        <option value="STRING">String</option> 
        <option value="NUMBER">Number</option> 
        ... 
    </select> 
    
    コントローラに結合することは、ドメインまたはコマンドオブジェクトを正常に動作

    データ :

    代わりにバインディング

    def save1(PsparameterCmd cmd) { 
        ... 
        instance.properties = cmd.properties 
    } 
    def save2() { 
        ... 
        instance.properties = params 
    } 
    

    カスタム列挙型のデータは、あなたがバインディングカスタムデータを使用することができ、これはこのような何かを生成します。 IDを列挙型の値に変換します。

    は異なるアプローチ(:http://docs.grails.org/2.5.0/guide/theWebLayer.html#dataBindingドキュメント):あるあなたは、そのタイプのためのグローバル・データ・バインダーを登録することができ (あなたがその列挙型のアプリで大量に使用している場合)あなたはその単一のフィールドにデータバインディングのアノテーションを指定することができます* * あなたは、リソースに登録する必要が

    import org.grails.databinding.converters.ValueConverter 
    class TypeEnumConverter implements ValueConverter { 
        boolean canConvert(value) { 
        value instanceof Integer 
        } 
        def convert(value) { 
        return TypeEnum.values().find({ it.id == value }) 
        } 
        Class<?> getTargetType() { 
        TypeEnum 
        } 
    } 
    

    class Psparameter implements java.io.Serializable { 
        @BindUsing({ obj, params -> 
        return TypeEnum.values().find({ it.id == params.int('typeId') }) 
        }) 
        TypeEnum typeEnum 
        ... 
    } 
    

    またはグローバルコンバータ(シングル使用のため)。グルーヴィー

    beans = { 
        typeEnumConverter(your.package.TypeEnumConverter) 
    } 
    

    注:私が知る限り(とちょうどテスト)、TypeEnum.getTypeEnumById(値)などの一切の一般的な方法はありません。そのため、上記の例ではTypeEnum.values()の検索を使用しています。

    +0

    あなたの入力のためのnorganosありがとう、私はその問題がenumsではなく、ドメイン上のプロパティを使用していることがわかりました。私の質問の編集を参照してください – nshweta

    +0

    私は昼食後に見てみましょう;-) – norganos

    関連する問題