DTO mapping and updating to a Database with Java, Dozer and Hibernate

Endo picture Endo · Mar 29, 2011 · Viewed 7.7k times · Source

I'm using Dozer to map Hibernate entities to their DTOs. A simplified example class is the following:

@Entity
public class Role {

     @Id
     @GeneratedValue
     @Column(name="RoleId", nullable=false)
     public int roleId;

     @Column(name="RoleName", nullable=false)
     @NotEmpty
     public String roleName;

     //get + set  (not for the roleId since its autogenerated)
}

   public class RoleDTO {   

     private int roleId;
     private String roleName;

     public RoleDTO(int roleId, String roleName) {
          this.roleId = roleId;
          this.roleName = roleName;
     }

     public RoleDTO() {}

     //gets + sets
  }

Now the mapping works fine, but I have a problem when trying to make an Update. Let's say I have a Role (1,"Administrator") in my database. My view first generates the DTO with the updated fields:

RoleDTO roleDTO = new RoleDTO(1, "admin");

Eventually the class that persists the Role receives the DTO and transforms it to an Entity class through Dozer to persist the changes:

Role role = DozerMapper.map(roleDTO,Role.class);    

At this point, my role entity has lost its ID, presumably because the ID column is defined as auto-increment, and I obviously can't update the null-ID entity.

So how should I approach this problem so that the ID and the updated fields get all mapped to the entity? I could always bring the entity object with hibernate and update each of its fields with the ones from the DTO and save it back, but it would defeat the whole purpose of using Dozer.

Thanks for any help.

Answer

Michal Bachman picture Michal Bachman · Mar 31, 2011

In this case, it is a perfectly valid approach to provide a setter for your roleId on the Role entity. Dozer will then set the ID as well. (Also, I assume your fields on Role aren't really public.)

With Dozer, you create an entity from the DTO. At that point, the entity is detached, i.e. not associated with a Hibernate session. You should then use session.merge(role) to persist the changes.