2015-11-30 79 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