Search code examples
javadozer

Mapping a collection of entities to a collection of their Ids


I'm building a RESTful service an I am using Dozer to map my entities retrieved by JPA/Hibernate to DTO and vice versa. Let's assume the following scenario. I have the classes EntityA and EntityB as well a my EntityADto as DTO.

@Entity
public class EntityA {
    @GeneratedValue
    @Id
    private Integer id;
    private EntityB entityB;

    /* Getter & Setter */
}

@Entity
public class EntityB {
    @GeneratedValue
    @Id
    private Integer id;

    /* Getter & Setter */
}

public class EntityADto {
    private Integer id;
    private Integer entityBId;

    /* Getter & Setter */
}

In this case I can map the entityB of type EntityB to my Integer entityBId by the following mapping:

<mapping>
  <class-a>EntityA</class-a>
  <class-b>EntityADto</class-b>
    <field>
      <a>entityB.id</a>
      <b>entityBId</b>
    </field>
</mapping>

This works so far.

But if I have a class EntityA with a Set of EntityB objects, I can't get it mapped to the ids.

@Entity
public class EntityA {
    @GeneratedValue
    @Id
    private Integer id;
    private Set<EntityB> entityBs;

    /* Getter & Setter */
}

public class EntityADto {
    private Integer id;
    private Set<Integer> entityBIds;

    /* Getter & Setter */
}

I'd rather avoid using a custom mapper and use XML configuration if possible.


Solution

  • But if I have a class EntityA with a Set of EntityB objects, I can't get it mapped to the ids.

    Try mapping the EntityB with Integer.

    <mapping>
      <class-a>EntityB</class-a>
      <class-b>Integer</class-b>
        <field>
          <a>entityBs.id</a>
          <b>entityBIds</b>
        </field>
    </mapping>
    

    This causes the following Exception: org.dozer.MappingException: No read or write method found for field (entityBIds) in class (class java.lang.Integer)

    We cannot map a Set<EntityB> with Set<Integer> using XML which results in the above Exception.

    I would rather recommend to change the model of your DTO's as below, which is even a good practice for design as well.

      public class EntityADto {
            private Integer id;
            private EntityBDto entityBDto;
    
            /* Getter & Setter */
        }
    
      public class EntityBDto {
            private Integer id;
    
            /* Getter & Setter */
        }
    

    Then if you have a class EntityA with a Set of EntityB objects. You can use the following.

    @Entity
    public class EntityA {
        @GeneratedValue
        @Id
        private Integer id;
        private Set<EntityB> entityBs;
    
        /* Getter & Setter */
    }
    
    public class EntityADto {
        private Integer id;
        private Set<EntityBDto> entityBDtos;
    
        /* Getter & Setter */
    }
    

    I'd recommend to update the model of the DTO's so that the Dozer Mapping can be done using the XML configuration.

       <mapping>
          <class-a>EntityB</class-a>
          <class-b>EntityBDto</class-b>
            <field>
              <a>entityBs.id</a>
              <b>entityBDtos.id</b>
            </field>
        </mapping>