将JDBI @BindBean与AutoValue一起使用

时间:2015-11-30 22:32:15

标签: java reflection jdbi auto-value

TLDR; JDBI @BindBean注释生成带有AutoValue生成类型的IllegalAccessException,因为生成的类型是包私有的,默认情况下默认情况下不能使用反射访问。

JDBI是不灵活还是通过AutoValue有解决方法? (以下完整问题)

快速背景

我正在尝试使用JDBI @BindBean注释,其类型的源是使用AutoValue生成的。

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使用反射,如果尝试使用find类型调用AutoValue_Foo,则结果为:

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

相关的JDBI代码为here。我从Java反射的角度理解,这可以使用setAccessible(true)解决,但这需要PR到JDBI。

所以问题如下:

  1. 有没有办法重构我的代码,我可以绑定Foo     使用AutoValue_Foo键入@BindBean而不创建新的JDBI     映射器?

  2. 有没有办法让@AutoValue生成类    public。我理解为什么这通常是不可取的    (推动人们使用界面而不是实现)。

  3. BindBeanFactory太不灵活了吗?应该利用       关于其他可用方法的setAccessible(true)       在他们的原始包裹之外?

1 个答案:

答案 0 :(得分:3)

JDBI版本2.71将包括使用@BindBean字段为type指定类型标记的功能。此类型标记将允许指定用于对提供的参数进行反射调用的类型。

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

使用此技术可以消除上述IllegalAccessException