2017-08-16 23 views
2

私はEktorpをCouchDB "ORM"として使用していますが、この質問はそれよりも一般的なようです。誰かがKotlinの突然変異子

@JsonInclude(NON_NULL) 
abstract class AbstractEntity(
     id: String?, 
     revision: String? 
) { 

    @JsonProperty("_id") 
    val id: String? = id 

    @JsonProperty("_rev") 
    val revision: String? = revision 

} 

@JsonInclude(NON_NULL) 
abstract class AbstractEntity(
     @JsonProperty("_id") 
     val id: String? = null, 
     @JsonProperty("_rev") 
     val revision: String? = null 
) 

の違いは何で説明してもらえますか?それに加えて

org.ektorp.InvalidDocumentException: Cannot resolve revision mutator in class com.scherule.calendaring.domain.Meeting 

    at org.ektorp.util.Documents$MethodAccessor.assertMethodFound(Documents.java:165) 
    at org.ektorp.util.Documents$MethodAccessor.<init>(Documents.java:144) 
    at org.ektorp.util.Documents.getAccessor(Documents.java:113) 
    at org.ektorp.util.Documents.getRevision(Documents.java:77) 
    at org.ektorp.util.Documents.isNew(Documents.java:85) 

私は

@JsonInclude(NON_NULL) 
abstract class AbstractEntity(
     @JsonProperty("_id") 
     var id: String? = null, 
     @JsonProperty("_rev") 
     var revision: String? = null 
) 

をすれば、私が得る:EKTORPは文句を言わない最初のケースでは

が、2番目のは言う

org.ektorp.DbAccessException: com.fasterxml.jackson.databind.exc.UnrecognizedPropertyException: Unrecognized field "_id" (class com.scherule.calendaring.domain.Meeting), not marked as ignorable 

問題は、最初のコードスニペットと2番目のコードスニペットがどのように違うのですか?最初のケースでは、Ektorpはミューテータがあると思っていますが、2番目にはありません。

ここでは、Ektorpがメソッド(setId、setRevision)を見つけるときに使用するように見えるコードスニペットを示します。

private Method findMethod(Class<?> clazz, String name, 
       Class<?>... parameters) throws Exception { 
      for (Method me : clazz.getDeclaredMethods()) { 
       if (me.getName().equals(name) 
         && me.getParameterTypes().length == parameters.length) { 
        me.setAccessible(true); 
        return me; 
       } 
      } 
      return clazz.getSuperclass() != null ? findMethod(
        clazz.getSuperclass(), name, parameters) : null; 
     } 

答えて

1

差は、クラス本体内に定義されたプロパティへの注釈のアプリケーションは、プライマリコンストラクタで宣言されたプロパティに注釈を付けるとは異なる方法です。

参照:言語リファレンスでAnnotation Use-site Targets:あなたはプロパティまたはプライマリコンストラクタのパラメータに注釈を付けているとき

、対応するKotlin要素から生成された複数のJava要素、したがって複数の可能な場所があります生成されたJavaバイトコード内のアノテーションのために使用されます。

あなたは利用サイトのターゲットを指定しない場合は、ターゲットが使用されている注釈の@Target注釈に従って選択されます。複数の適用対象がある場合は、以下のリストからの最初の適用対象が使用されている:あなたが宣言されたプロパティに注釈を付け

  • param
  • property
  • field
  • ので

、主コンストラクタであるコンストラクタパラメータであり、デフォルトでJavaバイトコードの注釈を取得します。それを変更するには、例えば、明示的に注釈対象を指定します。

abstract class AbstractEntity(
    @get:JsonProperty("_id") 
    val id: String? = null, 
    @get:JsonProperty("_rev") 
    val revision: String? = null 
) 
+0

を、これは*フィールドが生成されません*ヴァルを使用すると、「リビジョンミューテータを解決できない」理由を使用しながら、これはまだ例外を説明していませんVARの問題を解決するがそれはコンストラクタで(あなたの修正でも)何か...アイデアは何ですか?ロジックは、setterを作成しないので、valが機能しないはずであることを示唆しています...しかし、それは(フィールドとして使用される場合、より奇妙なものになるコンストラクタ宣言ではありません) – kboom

+0

私はこのツールを使用していないので、私はそれが新しいオブジェクトを作成するために使用できるコンストラクタを検出すると仮定することができます変更可能なプロパティを設定する代わりに、更新されたプロパティ値を使用してください。これで十分です。 – hotkey

+0

それ以外の方法では動作しません - フィールドの宣言(外部コンストラクタ)を使用する場合にのみ機能しますが、それでも "val"です。とにかく、これはektorpのlib実装の詳細の多くでなければなりません... – kboom