2010-07-22 89 views
1

我借用C++的「切片」意思。如何「切片」一個POJO

比方說,我哈瓦是威盛的Hibernate持久化一個簡單的POJO:

class Person { 
private long id; 
private String name; 
... 
// getters and setters here 
... 
} 

現在,當我從數據庫中檢索對象,我知道這是「儀表」由Hibernate(其真正的班是一個人 - 派生自動生成)。我想將它轉換回「普通」人物。例如,將使用Tnat將對象提交給XStream,並將結果僅包含Person包含的結果。

我可以通過定義一個拷貝構造函數來實現,但我不想爲每個ORM類編寫拷貝構造函數的麻煩(更不用說違反DRY原則了)。

所以我在想,如果

a)是已經有一個Java的lib是不是嗎? b)如果不是,使用反射寫一個是否可行?

在(b)的情況下,任何recomendations /準則/代碼骨架將不勝感激。

回答

3

豆映射庫Dozer在這方面做得非常出色,而且使用起來很簡單。

簡單地映射由Hibernate返回給它的bean的實例是自己的類:

Person person = session.load(...); 
BeanMapper mapper = ...; 
Person cleanPerson = mapper.map(person, Person.class); 

瞧,沒有更多的休眠代理或延遲加載集合!

+0

這是一個完美的解決方案。它甚至解決了我沒有提到的另一個問題,即一對多關係需要表示爲持久對象中的容器和XML-ed對象中的數組。非常感謝。 – 2010-07-22 00:43:52

+0

Dozer的真正目的是將TypeA映射到TypeB,並且能夠將該映射存儲在XML配置中而不是Java代碼中,所以它對於這種使用來說也是完美的(真正從一種類型映射到另一種類型)。 – 2010-07-22 00:57:25

1

該類org.apache.commons.beanutils.BeanUtilsBean可能幾乎做到了你想要的一切。 copyProperties方法將通過調用實體上的getter並在您提供的目標對象上尋找具有匹配屬性名稱的setter。您可能需要處理一些嵌套的實體,具體取決於您想要的行爲類型以及您/如何映射關係。

如果您需要更復雜一點,您可以註冊一個Converter以將您的嵌套實體類型轉換爲其他類型。

+0

謝謝。它部分解決了問題。但我想到更多關於像mybject = Slicer.slice(myObject,Person.class)的方法。它會創建一個新的Person對象(在第二個參數上調用newInstance)並遍歷它以知道要拷貝什麼。這樣,我完全可以避免編寫大小寫特定的代碼。 – 2010-07-22 00:17:53

0

你可以有不被持久化的對應包裹,像這樣的持續性信息的Person類:

public class Person implements Serializable 
{ 
    private String name; 
    // others. 
} 

public class PersistentPerson 
{ 
    private Long id; 
    private Person data; // 

    public Person getPerson() { return this.data; } 
} 

我不知道設計是值得的。這個雙重模式讓我在寫這個例子的時候有點嘔吐。

更大的問題是:爲什麼你認爲這是必要的?如果沒有好的方法可以告訴XStream在序列化時不包含id,我會說最好是編寫自己的javax.xml.bind.Marshallerjavax.xml.bind.Unmarshaller以獲得您想要的結果。

有比混雜你的整個設計更好的方法來解決這個問題。

+0

謝謝,但這會比做一個拷貝構造函數或像Pete建議的那樣使這兩個對象是獨立的更多工作(並且使代碼更少可讀)。 – 2010-07-22 00:38:57

+0

人完全獨立於PersistentPerson。你必須至少有一個單向關係。就我個人而言,我認爲分層分離不是那麼重要。 – duffymo 2010-07-22 00:56:50

1

有一個關於你的問題就在這裏一個有趣的討論

http://www.mojavelinux.com/blog/archives/2006/06/hibernate_get_out_of_my_pojo/

幾種解決方案的意見建議。特別是

http://code.google.com/p/entity-pruner/

http://www.anzaan.com/2010/06/serializing-cglib-enhanced-proxy-into-json-using-xstream/

我個人對分層巨大,而且會說,要通過線路或XML序列化類實際上應該是從你的數據訪問層類分開,這也可以解決問題。

class SerializablePerson 
{ 
    ... fields you care about ... 
    SerializablePerson(Person person) 
    { 
     ... set only what you care about ... 
    } 

}