【问题标题】:Using JDBI @BindBean with AutoValue将 JDBI @BindBean 与 AutoValue 一起使用
【发布时间】:2016-03-04 17:14:24
【问题描述】:

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

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

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

所以问题如下:

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

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

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

【问题讨论】:

  • 您可以使用 Lombok 的 @Data (projectlombok.org/features/Data.html) 代替 @AutoValue。它在您的类中生成样板,而不是创建实现类型。可能不是您正在寻找的东西,但它对我来说非常有用。
  • @Jorn 很想知道 Lombok 的作品。不幸的是,我被锁定在 AutoValue 中,但这可能对其他具有更大灵活性的工程师有用。
  • 请向 JDBI 提交 PR。我会带领它度过。

标签: java reflection jdbi auto-value


【解决方案1】:

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

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

使用这种技术,您可以消除上述IllegalAccessException

【讨论】:

    猜你喜欢
    • 2017-06-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-01-14
    • 1970-01-01
    • 2018-03-14
    • 1970-01-01
    相关资源
    最近更新 更多