valores seguras otro objeto formas examen copiar como java object lambdaj

java - seguras - Patrón DTO: la mejor manera de copiar propiedades entre dos objetos



copiar valores de un objeto a otro java (6)

En la arquitectura de mi aplicación, normalmente envío el objeto o la lista de objetos desde la capa de acceso a datos a la capa web a través de la capa de servicio, en la que estos objetos se transforman de un objeto DAO a un objeto DTO y viceversa. La capa web no tiene acceso a objetos DAO y la capa DAO no usa DTO.

Para demostrar, generalmente escribo el código como:

@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; }

Aquí el usuario es la entidad de la base de datos:

@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; } }

Y este es el 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; } }

Entonces me preguntaba si esta es la única forma de copiar propiedades entre dos objetos. Supongo que no estoy seguro. También estoy usando lambdaj , entonces ¿hay un método en esta API mediante el cual puedo copiar todas estas propiedades para crear una lista de otros objetos?

Este tema puede sonar subjetivo, pero realmente quiero saber de ustedes expertos las formas en que se puede hacer la transformación de un objeto de una forma a otra donde los campos máximos tienen la misma cadena.


¿No funcionaría lo que está buscando la función de proyecto de lambdaj?

Se verá algo como esto:

List<UserDTO> userNDtos = project(users, UserDTO.class, on(User.class).getUserName(), on(User.class).getFullName(), .....);

(Defina el constructor para UserDTO en consecuencia ...)

También vea here para ejemplos ...


Le sugiero que use una de las bibliotecas de los mapeadores: Mapstruct , ModelMapper , etc. Con Mapstruct, su mapeador se verá así:

@Mapper public interface UserMapper { UserMapper INSTANCE = Mappers.getMapper( UserMapper.class ); UserDTO toDto(User user); }

El objeto real con todos los getters y setters se generará automáticamente desde esta interfaz. Puedes usarlo como:

UserDTO userDTO = UserMapper.INSTANCE.toDto(user);

También puede agregar un poco de lógica para su activeText archivado usando la anotación @AfterMapping .


Puede usar la reflexión para encontrar todos los métodos get en sus objetos DAO y llamar al método de set equivalente en el DTO . Esto solo funcionará si existen todos esos métodos. Debería ser fácil encontrar un código de ejemplo para esto.


Puedes echar un vistazo a dozer que es un

Java Bean to Java Bean mapper que recursivamente copia datos de un objeto a otro. Por lo general, estos Java Beans serán de diferentes tipos complejos.

Otro enlace mejor ...


Puedes usar Apache Commmons Beanutils . La API es

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

Copia los valores de propiedad del bean "origen" al bean "destino" para todos los casos donde los nombres de las propiedades son los mismos.

Ahora me voy fuera del tema. El uso de DTO se considera principalmente un antipatrón en EJB3. Si su DTO y sus objetos de dominio son muy parecidos, realmente no hay necesidad de duplicar códigos. DTO todavía tiene ventajas, especialmente para ahorrar ancho de banda de red cuando se trata de acceso remoto. No tengo detalles sobre la arquitectura de su aplicación, pero si las capas de las que habló son capas lógicas y no cruzan la red, no veo la necesidad de DTO.


Tenía una aplicación que necesitaba convertir de una entidad JPA a DTO, y pensé en ello y finalmente surgió usando org.springframework.beans.BeanUtils.copyProperties para copiar propiedades simples y también extender y usar org.springframework.binding.convert.service.DefaultConversionService para convertir propiedades complejas.

En detalle mi servicio fue algo como esto:

@Service("seedingConverterService") public class SeedingConverterService extends DefaultConversionService implements ISeedingConverterService { @PostConstruct public void init(){ Converter<Feature,FeatureDTO> featureConverter = new Converter<Feature, FeatureDTO>() { @Override public FeatureDTO convert(Feature f) { FeatureDTO dto = new FeatureDTO(); //BeanUtils.copyProperties(f, dto,"configurationModel"); BeanUtils.copyProperties(f, dto); dto.setConfigurationModelId(f.getConfigurationModel()==null?null:f.getConfigurationModel().getId()); return dto; } }; Converter<ConfigurationModel,ConfigurationModelDTO> configurationModelConverter = new Converter<ConfigurationModel,ConfigurationModelDTO>() { @Override public ConfigurationModelDTO convert(ConfigurationModel c) { ConfigurationModelDTO dto = new ConfigurationModelDTO(); //BeanUtils.copyProperties(c, dto, "features"); BeanUtils.copyProperties(c, dto); dto.setAlgorithmId(c.getAlgorithm()==null?null:c.getAlgorithm().getId()); List<FeatureDTO> l = c.getFeatures().stream().map(f->featureConverter.convert(f)).collect(Collectors.toList()); dto.setFeatures(l); return dto; } }; addConverter(featureConverter); addConverter(configurationModelConverter); } }