2010-07-22 183 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 ... 
    } 

}