Dozer mapping for Hibernate object to DTO

sylsau picture sylsau · May 13, 2010 · Viewed 17.1k times · Source

I try to use Dozer to convert my domain entity to DTO objects. So, I want to convert PersistentList, PersistentBag, ... from my domain entity to ArrayList, ... in my DTO objects to avoid lazy problem.

This is an example of two of my domain entity :

public class User {
      private Collection<Role> roles;
      ...
}

public class Role {
      private Collection<User> users;
      ...
}

My DTO objects are the same except that class are of types DTO. So, to convert domain to DTO objects, I use the following Dozer mapping :

 <configuration>
  <custom-converters>
   <converter type=com.app.mapper.converter.BagConverter">
    <class-a>org.hibernate.collection.PersistentBag</class-a>
    <class-b>java.util.List</class-b>
   </converter>
  </custom-converters>
 </configuration>

 <mapping>
  <class-a>com.app.domain.User</class-a>
  <class-b>com.app.dto.UserDTO</class-b>
 </mapping>

 <mapping>
  <class-a>com.app.domain.Role</class-a>
  <class-b>com.app.dto.RoleDTO</class-b>
 </mapping>

BagConverter is a Dozer custom converter and that is its code :

  public class BagConverter<T> extends DozerConverter<PersistentBag, List>{

 public BagConverter() {
  super(PersistentBag.class, List.class);
 }

 public PersistentBag convertFrom(List source, PersistentBag destination) {
  PersistentBag listDest = null;

  if (source != null) {

   if (destination == null) {
    listDest = new PersistentBag();
   } else {
    listDest = destination;
   }

   listDest.addAll(source);
  }

  return listDest;
 }

 public List convertTo(PersistentBag source, List destination) {
  List listDest = null;

  if (source != null) {

   if (destination == null) {
    listDest = new ArrayList<T>();
   } else {
    listDest = destination;
   }

   if (source.wasInitialized()) {
    listDest.addAll(source);
   }
  }

  return listDest;
 }}

So, I get a User object that contains a PersistentBag with roles. I apply dozer mapper map on that object to obtain UserDTO object. The result that I obtain is a UserDTO object with a ArrayList of Role and no an ArrayList of RoleDTO like I wished.

I thought that even if I used custom converter, dozer will convert the content of my list. It's not the right way ? If no, how to do to convert my domain entity to dto object by replacing persitent collections to classic java collections ?

Thanks for your help.

Sylvain.

Answer

Grzegorz Oledzki picture Grzegorz Oledzki · May 13, 2010

Unfortunately when you register a CustomConverter you take the whole responsibility for mapping an object (collection in your case) including all its contents, properties, elements, etc.

As I see now (I didn't see it before, it has to be some kind of new feature). There's a possibility to use MapperAware interface as described at the end of chapter for Custom Type Converters in Dozer docs. I guess this is exactly what would suite your needs.