2011-12-05 55 views
3

我使用PropertyUtils.copyProperties()通過反射來複制對象的屬性,並且它用於很好地工作。但是最近它開始沒有做任何事情。PropertyUtils.copyProperties何時可以靜默失敗?

它不會拋出異常,但不會複製任何字段。儘管源對象中存在非空字段,但目標對象的所有字段仍爲空。

我不知道如何重現這一點。對我而言,它一貫發生,但它在一個我不能在這裏發佈的項目中。該項目使用Play Framework,它執行一些字節碼操作,因此可能是罪魁禍首。

有什麼建議或想法可能導致這種情況,或如何調試?我可以嘗試的替代場複印機也是受歡迎的(我之前嘗試過BeanUtils,但因爲我現在不記得的一些警告而切換到PropertyUtils)。

+0

您是否升級到更新版本的beanutils?你能否將你的代碼恢復到較早的版本以找出改變了什麼? – Gray

+0

@格雷 - 我沒有改變beanutils版本......我不確定是什麼讓它停止工作。當我試圖單獨重現問題時,它立即複製 - 所以現在我實際上不確定是什麼使它起作用。看看我的回答:http://stackoverflow.com/a/8385725/11236 – ripper234

回答

2

。它今天發生在我身上。我只是用它做了一些小測試,但它不起作用。這裏是代碼:

static class TesteP { 

    private String a; 
    private String b; 
    private String c; 

    public String getA() { 
     return this.a; 
    } 


    public void setA(String a) { 
     this.a = a; 
    } 



    public String getB() { 
     return this.b; 
    } 


    public void setB(String b) { 
     this.b = b; 
    } 


    public String getC() { 
     return this.c; 
    } 


    public void setC(String c) { 
     this.c = c; 
    } 

    @Override 
    public String toString() { 
     return new ToStringBuilder(this.getClass()).add("a", this.a).add("b", this.b).toString(); 
    } 

} 

static class RestP { 

    private String a; 

    public String getA() { 
     return this.a; 
    } 

    public void setA(String a) { 
     this.a = a; 
    } 

    @Override 
    public String toString() { 
     return this.a; 
    } 
} 

public static void main(String[] args) 
     throws IllegalAccessException, InvocationTargetException, NoSuchMethodException { 
    TesteP p = new TesteP(); 
    p.setA("AAAA"); 
    p.setB("BBB"); 
    TesteP pp = new TesteP(); 
    RestP p2 = new RestP(); 
    p2.setA("aaaa"); 
    PropertyUtils.copyProperties(p,p2); 

} 

它解決了這個問題,使公開課程。也許你的一個班級不公開。這裏是我的情況下的解決方案:

public static class TesteP { 

    private String a; 
    private String b; 
    private String c; 


    public String getA() { 
     return this.a; 
    } 


    public void setA(String a) { 
     this.a = a; 
    } 


    public String getB() { 
     return this.b; 
    } 


    public void setB(String b) { 
     this.b = b; 
    } 


    public String getC() { 
     return this.c; 
    } 


    public void setC(String c) { 
     this.c = c; 
    } 

    @Override 
    public String toString() { 
     return new ToStringBuilder(this.getClass()).add("a", this.a).add("b", this.b).toString(); 
    } 

} 

public static class RestP { 

    private String a; 

    public String getA() { 
     return this.a; 
    } 

    public void setA(String a) { 
     this.a = a; 
    } 

    @Override 
    public String toString() { 
     return this.a; 
    } 
} 

public static void main(String[] args) 
     throws IllegalAccessException, InvocationTargetException, NoSuchMethodException { 
    TesteP p = new TesteP(); 
    p.setA("AAAA"); 
    p.setB("BBB"); 
    TesteP pp = new TesteP(); 
    RestP p2 = new RestP(); 
    p2.setA("aaaa"); 
    PropertyUtils.copyProperties(p,p2); 

} 
0

推土機是一個更復雜的豆類複印機,你可能想嘗試。

要調試你的PropertyUtils問題,創建一個單元測試,然後逐步完成。

+0

看看我的答案 - 我相信問題是我有一個只讀屬性。我只是用我自己的代碼來處理這種情況 - 它工作正常。 – ripper234

+0

轉載請點這裏:https://github.com/ripper234/Play-doesn-t-work-with-PropertyUtils.copyProperties/blob/master/test/BasicTest.java – ripper234

+0

嗯,屬性與字段不一樣,所以我猜Play Framework的自動生成訪問器沒有被拾取。我也猜你已經明白了。 – artbristol

1

我從this answer的代碼並運行它,它失敗了,因爲我只有一個只寫字段(只有setter,沒有getter)。賠率是這是搞亂PropertyUtils。

我發現調用Introspector.getBeanInfo(MyModel.class).getPropertyDescriptors()只返回屬性的部分列表。轉載於this github repository

我加了一個電話Introspector.flushCaches();,希望它能解決問題......只有它沒有。

作爲一種變通方法,我實現複製,而不是回答對的BeanUtils領域的方法:我想我想通了

public static <T> void copyFields(T target, T source) throws Exception{ 
    Class<?> clazz = source.getClass(); 

    for (Field field : clazz.getFields()) { 
     Object value = field.get(source); 
     field.set(target, value); 
    } 
}