开发者

How to "slice" a POJO

开发者 https://www.devze.com 2023-01-08 03:01 出处:网络
I\'m borrowing the \"slice\" meaning from C++. Let\'s say I hava a simple POJO that\'s persisted via Hibernate:

I'm borrowing the "slice" meaning from C++.

Let's say I hava a simple POJO that's persisted via Hibernate:

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

Now, when I retrieve an object from the database I know it was "instrumented" by Hibernate (its real class is a Person-derived generated automatically). I want to convert it back to a "plain" person object. Tnat would be used, for instance, to submit the object to XStream and have the result containing only what Person contains.

I could do it by defining a copy constructor, but I don't want to have the hassle of having to write copy constructors for every ORM class (not to mention the violation of DRY principle).

So I was wondering if

a) 开发者_运维百科is there already a Java lib that does it? b) If not, would it be practical to write one using reflection?

In case of (b), any recomendations/guidelines/code skeletons would be appreciated.


The bean mapping library Dozer does an excellent job of this and is dead simple to use.

Simply map an instance of the bean returned by Hibernate to it's own class:

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

voila, no more Hibernate proxies or lazy-loaded collections!


The class org.apache.commons.beanutils.BeanUtilsBean probably does almost everything you want. The copyProperties method will go through calling the getters on your Entity and looking for setters with a matching property name on a target object you provide. You may need to handle some nested entities, depending on what kind of behavior you want and if/how you map relationships.

If you need to get more sophisticated you can register a Converter for turning your nested entity types into something else as well.


There is an interesting discussion about your problem here

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

Several solutions are proposed in the comments. In particular

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

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

I personally am huge on layer separation, and would argue that classes that you want to serialize across the wire or to XML should actually be separate from your data access layer classes, which would also solve the problem.

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

}


You could have a Person class without persistence information wrapped by a persistent counterpart, like this:

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

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

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

I'm not sure the design is worth it. The dual model makes me throw up in my mouth a little, just while writing this example.

The larger question is: Why do you think this is necessary? IF there's no good way to tell XStream to not include the id when serializing, I'd say it'd be better to write your own javax.xml.bind.Marshaller and javax.xml.bind.Unmarshaller to get what you want.

There are better ways to solve this problem than bastardizing your entire design.

0

精彩评论

暂无评论...
验证码 换一张
取 消