我正在借用C ++中的“切片”含义。
让我说我有一个简单的POJO,它通过Hibernate持续存在:
class Person {
private long id;
private String name;
...
// getters and setters here
...
}
现在,当我从数据库中检索一个对象时,我知道它是由Hibernate“检测”的(它的真正类是一个自动生成的Person)。我想将它转换回“普通”人物。例如,Tnat将用于将对象提交给XStream并使结果仅包含Person包含的内容。
我可以通过定义一个复制构造函数来实现,但我不想为每个ORM类编写复制构造函数的麻烦(更不用说违反DRY原则)。
所以我想知道是否
a)是否有一个Java库可以做到这一点? b)如果没有,用反射写一个是否可行?
如果是(b),任何推荐/指南/代码骷髅都将受到赞赏。
答案 0 :(得分:3)
bean映射库Dozer做得非常好,并且使用起来很简单。
只需将Hibernate返回的bean实例映射到它自己的类:
Person person = session.load(...);
BeanMapper mapper = ...;
Person cleanPerson = mapper.map(person, Person.class);
瞧,不再有Hibernate代理或延迟加载的集合了!
答案 1 :(得分:1)
班级org.apache.commons.beanutils.BeanUtilsBean
几乎可以完成你想要的一切。 copyProperties方法将通过调用实体上的getter并查找在您提供的目标对象上具有匹配属性名称的setter。您可能需要处理一些嵌套实体,具体取决于您想要的行为类型以及您是否/如何映射关系。
如果您需要更复杂,可以注册一个转换器,以便将嵌套的实体类型转换为其他类型。
答案 2 :(得分: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 ...
}
}
答案 3 :(得分: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.Marshaller
和javax.xml.bind.Unmarshaller
来获得你想要的东西。
有更好的方法来解决这个问题,而不是整个设计的混蛋。