Java – Dozer mapping for Hibernate object to DTO

dozerdtohibernatejavamapping

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.

Best Answer

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.