views:

1251

answers:

3

Hello,

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.

A: 

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.

Grzegorz Oledzki
A: 

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.

I get the last sentence but I don't understand why you need to deal with o.h.c.PersistentBag (and so on) since this class is a List. Just use something like this:

<mapping>
  <class-a>com.myapp.domain.User</class-a>
  <class-b>com.myapp.dto.UserDTO</class-b>
  <field>
    <a>roles</a>
    <b>roles</b>
    <a-hint>com.myapp.domain.Role</a-hint>
    <b-hint>com.myapp.dto.RoleDTO</b-hint>
  </field>
</mapping>

And perform the conversion before to detach entities (that's the key of your problem).

Pascal Thivent
I guess the reason is that OP is using some methods not declared in `List` interface, e.g. `wasInitialized()`.
Grzegorz Oledzki
My main goal is to transfer DTO object to presentation layer that is in GWT so hibernate collections aren't suported for serialization by GWT.So, I tought to convert hibernate collections in classic java collections to avoid that problem.
sylsau
@sylsau Yes, I get that. But I don't see how dealing with `PersistentBag` does solve anything. You just need to make the conversion when Entities are still attached.
Pascal Thivent
A: 

I also tested an other solution witout custom converter like that :

<mapping>
    <class-a>com.myapp.domain.User</class-a>
    <class-b>com.myapp.dto.UserDTO</class-b>
    <field>
        <a>roles</a>
        <b>roles</b>
        <a-hint>com.myapp.domain.Role</a-hint>
        <b-hint>com.myapp.dto.RoleDTO</b-hint>
    </field>
</mapping>

There is another problem. When Dozer try to convert roles from User to roles of RoleDTO in UserDTO, I get a lazy initialisation exception from Hibernate because roles in User is in EAGER mode.

So, I don't know how to do that mapping. I continue to search a way to solve these problems

sylsau
Do the conversion before to detach entities, that's all.
Pascal Thivent