将 JDBI @BindBean 与 AutoValue 结合使用
Using JDBI @BindBean with AutoValue
TLDR;
JDBI @BindBean
注释生成一个 IllegalAccessException
和 AutoValue 生成的类型,因为生成的类型是包私有的,默认情况下不能使用反射访问。
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
}
注意 class 是私有包!
现在,如果我尝试使用 @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。
所以问题如下:
有没有一种方法可以重构我的代码,使我可以绑定 Foo
使用 @BindBean
键入 AutoValue_Foo
而不创建新的 JDBI
映射器?
有没有办法让 @AutoValue
生成 classes
public
。我明白为什么这通常是不可取的
(促使人们使用接口而不是实现)。
BindBeanFactory
是不是太死板了?它应该利用
setAccessible(true)
关于其他可用的方法
在他们的原始包裹之外?
JDBI 2.71 版将包含使用 type
字段将类型标记指定为 @BindBean
的功能。此类型标记将允许指定用于对提供的参数进行反射调用的类型。
@SqlQuery("select * from baz where bar = :foo.bar")
Condition find(@BindBean(value="foo", type=Foo.class) Foo foo);
使用此技术可以消除上述 IllegalAccessException
。
TLDR;
JDBI @BindBean
注释生成一个 IllegalAccessException
和 AutoValue 生成的类型,因为生成的类型是包私有的,默认情况下不能使用反射访问。
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
}
注意 class 是私有包!
现在,如果我尝试使用 @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。
所以问题如下:
有没有一种方法可以重构我的代码,使我可以绑定
Foo
使用@BindBean
键入AutoValue_Foo
而不创建新的 JDBI 映射器?有没有办法让
@AutoValue
生成 classespublic
。我明白为什么这通常是不可取的 (促使人们使用接口而不是实现)。BindBeanFactory
是不是太死板了?它应该利用setAccessible(true)
关于其他可用的方法 在他们的原始包裹之外?
JDBI 2.71 版将包含使用 type
字段将类型标记指定为 @BindBean
的功能。此类型标记将允许指定用于对提供的参数进行反射调用的类型。
@SqlQuery("select * from baz where bar = :foo.bar")
Condition find(@BindBean(value="foo", type=Foo.class) Foo foo);
使用此技术可以消除上述 IllegalAccessException
。