2015-11-30 42 views
4

TLDR; 的JDBI @BindBean注释生成与AutoValue一个IllegalAccessException生成的类型,因为所生成的类型是包专用,默认情况下无法通过默认使用反射来访问。使用JDBI @BindBean与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 
} 

注意这个类是包私有!

现在,如果我尝试使用@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代码是here。我从Java反思的角度理解,这可以使用setAccessible(true)来解决,但是这需要PR到JDBI。

所以,问题如下:

  1. 是否有办法来调整自己的代码,我可以在不产生新的JDBI 映射器绑定的FooAutoValue_Foo使用@BindBean

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

  3. 是在BindBeanFactory太执着?它应该利用上可在其他 其原产包外的方法 setAccessible(true)

+0

您可以使用Lombok的'@ Data'(https://projectlombok.org/features/Data.html)而不是'@ AutoValue'。它在你的类中生成样板文件,而不是制作实现类型。可能不是你正在寻找的东西,但它对我很好。 – Jorn

+0

@Jorn有趣的知道龙目岛的作品。我不幸被锁定在AutoValue中,但这对其他具有更大灵活性的工程师可能会有用。 – vpiTriumph

+0

请将公关提交给JDBI。我会牧养它。 – qualidafial

回答

3

JDBI的版本2.71将包括使用type字段指定一个类型令牌@BindBean的能力。此类型令牌将允许指定用于根据提供的参数进行反射调用的类型。

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

使用这种技术就可以消除上述的IllegalAccessException