6

TLDR; 生成された型はパッケージ プライベートであり、デフォルトではリフレクションを使用してデフォルトでアクセスできないため、 JDBI@BindBeanアノテーションはwith AutoValue で生成された型を生成します。IllegalAccessException

JDBI は柔軟性がないのでしょうか、それとも AutoValue による回避策はありますか? (以下の質問全文)

簡単な背景

ソースが AutoValue を使用して生成された型でJDBI@BindBeanアノテーションを使用しようとしています。

package com.example;

@AutoValue
public abstract class Foo {
  public String getBar();
}

問題は、生成されたコードが次のようになることです。

package com.example;

@AutoValue
class AutoValue_Foo extends Foo {
  private final String bar;

  @Override
  public String getBar() {
    return this.bar;
  }

  // toString, equals, hashCode
}

クラスがパッケージ プライベートであることに注意してください。

を使用しようとする@BindBeanと、たとえば次のようになります。

@SqlQuery("select * from baz where bar = :foo.bar")
Condition find(@BindBean("foo") Foo foo);

AutoValue_Fooパッケージは非公開であり、BindBeanFactoryリフレクションを使用するためfindAutoValue_Foo型で呼び出しを試みると、結果は次のようになります。

java.lang.IllegalAccessException: ... can not access a member of class com.example.Foo with modifiers "public"

関連する JDBI コードはこちらです。Java リフレクションの観点からは、これを使用して解決できることは理解していますsetAccessible(true)が、それには JDBI への PR が必要です。

したがって、質問は次のとおりです。

  1. 新しい JDBI マッパーを作成せずFooにタイプAutoValue_Fooをバインドできるコードを再構築する方法はありますか?@BindBean

  2. @AutoValueであるクラスを生成 する方法はありますかpublic。これが一般的に望ましくない理由を理解しています(人々に実装ではなくインターフェイスを使用するように促します)。

  3. BindBeanFactory柔軟性がありませんか?setAccessible(true)元のパッケージの外部で利用可能なメソッドを利用する必要 がありますか?

4

1 に答える 1

5

JDBI のバージョン 2.71 には、フィールドを@BindBean使用するためのタイプ トークンを指定する機能が含まれますtype。この型トークンを使用すると、指定された引数に対してリフレクション呼び出しを行うために使用される型を指定できます。

@SqlQuery("select * from baz where bar = :foo.bar") Condition find(@BindBean(value="foo", type=Foo.class) Foo foo);

この手法を使用すると、IllegalAccessException上記を排除できます。

于 2015-12-12T15:57:27.547 に答える