Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

DTO pattern: Best way to copy properties between two objects

In my application's architecture I usually send the object or list of objects from the data access layer to the web layer via the service layer, in which these objects get transformed from a DAO object to a DTO object and vice versa. The web layer don't have any access to DAO objects and the DAO layer do not use DTOs.

To demonstrate, I usually write the code as:

@Transactional(readOnly = true) public List<UserDTO> getAllUserAsUserDTO() {     List<UserDTO> userDTOs = new ArrayList<UserDTO>();      for(User user : getAllUser()) {         userDTOs.add(constructUserDTO(user));     }      return userDTOs; }  private UserDTO constructUserDTO(User user) {     UserDTO userDTO = new UserDTO();     userDTO.setFullName(user.getFullName());     userDTO.setId(user.getId());     userDTO.setUsername(user.getUsername());     userDTO.setRole(user.getRole());     userDTO.setActive(user.isActive());     userDTO.setActiveText(user.isActive() ? "Active" : "Inactive");     return userDTO; } 

Here the user is the database entity:

@javax.persistence.Entity @Table(name = "USER") public class User extends Entity {      @Transient     private static final long serialVersionUID = -112950002831333869L;      private String username;     private String fullName;     private boolean active;     private String role;     // other fields      public User() {         super();     }      @NaturalId     @Column(name = "USERNAME", nullable = false)     public String getUsername() {         return username;     }      public void setUsername(String username) {         this.username = username;     }      @Column(name = "FULL_NAME")     public String getFullName() {         return fullName;     }      public void setFullName(String fullName) {         this.fullName = fullName;     }      @Column(name = "ACTIVE", nullable = false)     public boolean isActive() {         return active;     }      public void setActive(boolean active) {         this.active = active;     }      @Column(name = "ROLE")     public String getRole() {         return role;     }      public void setRole(String role) {         this.role = role;     } } 

And this is the UserDTO:

public class UserDTO extends BaseDTO {      private static final long serialVersionUID = -3719463614753533782L;      private String username;     private String fullName;     private String role;     private String activeText;     private Boolean active;     //other properties      public UserDTO() {         super();     }      public String getUsername() {         return username;     }      public void setUsername(String username) {         this.username = username;     }      public String getFullName() {         return fullName;     }      public void setFullName(String fullName) {         this.fullName = fullName;     }      public String getRole() {         return role;     }      public void setRole(String role) {         this.role = role;     }      public String getActiveText() {         return activeText;     }      public void setActiveText(String activeText) {         this.activeText = activeText;     }      public Boolean getActive() {         return active;     }      public void setActive(Boolean active) {         this.active = active;     } } 

So I was wondering if this is the only way to copy properties between two objects. I guess I am not sure. Also I am using lambdaj, so is there a method in this API by which I can copy all these properties to create list of other objects?

This topic may be sounds subjective, but I really want to know from you experts the ways by which the transformation of object from one form to another can be done where the maximum fields are having same string.

like image 785
Tapas Bose Avatar asked Feb 27 '13 16:02

Tapas Bose


Video Answer


2 Answers

You can use Apache Commmons Beanutils. The API is

org.apache.commons.beanutils.PropertyUtilsBean.copyProperties(Object dest, Object orig).

It copies property values from the "origin" bean to the "destination" bean for all cases where the property names are the same.

Now I am going to off topic. Using DTO is mostly considered an anti-pattern in EJB3. If your DTO and your domain objects are very alike, there is really no need to duplicate codes. DTO still has merits, especially for saving network bandwidth when remote access is involved. I do not have details about your application architecture, but if the layers you talked about are logical layers and does not cross network, I do not see the need for DTO.

like image 132
Lan Avatar answered Sep 23 '22 21:09

Lan


You can have a look at dozer which is a

Java Bean to Java Bean mapper that recursively copies data from one object to another. Typically, these Java Beans will be of different complex types.

Another better link...

like image 41
pgras Avatar answered Sep 24 '22 21:09

pgras