如何“切片”POJO

时间:2010-07-22 00:04:13

标签: java reflection pojo slice

我正在借用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),任何推荐/指南/代码骷髅都将受到赞赏。

4 个答案:

答案 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.Marshallerjavax.xml.bind.Unmarshaller来获得你想要的东西。

有更好的方法来解决这个问题,而不是整个设计的混蛋。