I have User entity that has relationship to other entities(Order,Profile) When I assemble entity from dto and back I need assemble order and profile entity too.
User entity:
@Table(name = "user_info")
@Entity
@Getter
@Setter
public class User implements Serializable {
private static final long serialVersionUID = 1789771068899105277L;
@Id
@GeneratedValue
@Column(name = "userId",columnDefinition = "BINARY(16)")
private UUID userId ;
@Column(name = "login", unique = true, length = 20)
private String login;
@Column(name = "userPassword", length = 100)
private String password;
@Column(name = "userEmail", unique = true, length = 320)
private String userEmail;
@OneToOne(mappedBy = "user", cascade = CascadeType.ALL,
fetch = FetchType.LAZY, optional = false)
private Profile profile;
@OneToMany(mappedBy = "user", cascade = CascadeType.ALL, orphanRemoval = true)
private Set<Role> roles = new HashSet<>();
@OneToMany(mappedBy = "user", cascade = CascadeType.ALL, orphanRemoval = true)
private List<Order> orders = new ArrayList<>();
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
User user = (User) o;
return Objects.equals(getUserId(), user.getUserId());
}
@Override
public int hashCode() {
return Objects.hash(getUserId());
}
@Override
public String toString() {
final StringBuilder sb = new StringBuilder("User{");
sb.append("userId=").append(userId);
sb.append(", login='").append(login).append('\'');
sb.append(", password='").append(password).append('\'');
sb.append(", userEmail='").append(userEmail).append('\'');
sb.append('}');
return sb.toString();
}
}
@Override
public int hashCode() {
return Objects.hash(getId(), getUserAuthority());
}
@Override
public String toString() {
final StringBuilder sb = new StringBuilder("Role{");
sb.append("id=").append(id);
sb.append(", userAuthority='").append(userAuthority).append('\'');
sb.append(", user=").append(user);
sb.append('}');
return sb.toString();
}
}
For example If I need transform User entity to Dto I need assembler:
public interface Assembler <E,D>{
D mergeAggregateIntoDto(E entity);
E mergeDtoIntoAggregate(D dto);
}
@Service
public class UserAssembler implements Assembler<User, UserDto>{
@Autowired
private CarDao carDao;
@Override
public UserDto mergeAggregateIntoDto(User entity) {
UserDto userDto = new UserDto();
userDto.setUserId(entity.getUserId());
userDto.setUserEmail(entity.getUserEmail());
userDto.setLogin(entity.getLogin());
userDto.setPassword(entity.getPassword());
userDto.setProfile(mergeAggregateIntoDto(entity.getProfile()));
userDto.setRoles(entity.getRoles().stream().map(this::mergeAggregateIntoDto).collect(Collectors.toSet()));
userDto.setOrders(entity.getOrders().stream().map(this::mergeAggregateIntoDto).collect(Collectors.toList()));
return userDto;
}
@Override
public User mergeDtoIntoAggregate(UserDto dto) {
User user = new User();
Map<UUID,Car> uuidCarMap = getCars(dto);
Profile profile = mergeDtoIntoAggregate(dto.getProfile());
profile.setUser(user);
user.setUserId(dto.getUserId());
user.setUserEmail(dto.getUserEmail());
user.setLogin(dto.getLogin());
user.setPassword(dto.getPassword());
user.setProfile(profile);
user.setRoles(dto.getRoles().stream().map(roleDto->{
Role role = mergeDtoIntoAggregate(roleDto);
role.setUser(user);
return role;
}).collect(Collectors.toSet()));
user.setOrders(dto.getOrders().stream().map(orderDto -> {
Order order = mergeDtoIntoAggregate(orderDto);
order.setUser(user);
order.setCar(uuidCarMap.get(orderDto.getCarId()));
return order;
}).collect(Collectors.toList()));
return user;
}
private Map<UUID, Car> getCars(UserDto userDto){
List<UUID> carIds = userDto.getOrders().stream().map(OrderDto::getCarId).collect(Collectors.toList());
List<Car> cars = carDao.findByIds(carIds);
return cars.stream().collect(Collectors.toMap(Car::getCarId, Function.identity()));
}
private ProfileDto mergeAggregateIntoDto(Profile profile){
ProfileDto profileDto = new ProfileDto();
profileDto.setProfileId(profile.getProfileId());
profileDto.setUserId(profile.getUser().getUserId());
profileDto.setAccountBalance(profile.getAccountBalance());
profileDto.setUserFirstName(profile.getUserFirstName());
profileDto.setUserSurName(profile.getUserSurName());
profileDto.setUserRegistrationDate(profile.getUserRegistrationDate());
return profileDto;
}
private Profile mergeDtoIntoAggregate(ProfileDto profileDto){
Profile profile = new Profile();
profile.setProfileId(profileDto.getProfileId());
profile.setAccountBalance(profileDto.getAccountBalance());
profile.setUserFirstName(profileDto.getUserFirstName());
profile.setUserSurName(profileDto.getUserSurName());
profile.setUserRegistrationDate(profileDto.getUserRegistrationDate());
return profile;
}
private RoleDto mergeAggregateIntoDto(Role role){
RoleDto roleDto = new RoleDto();
roleDto.setId(role.getId());
roleDto.setUserAuthority(role.getUserAuthority());
roleDto.setUserId(role.getUser().getUserId());
return roleDto;
}
private Role mergeDtoIntoAggregate(RoleDto roleDto){
Role role = new Role();
role.setUserAuthority(roleDto.getUserAuthority());
role.setId(roleDto.getId());
return role;
}
private OrderDto mergeAggregateIntoDto(Order order){
OrderDto orderDto = new OrderDto();
orderDto.setOrderCost(order.getOrderCost());
orderDto.setOrderDate(order.getOrderDate());
orderDto.setOrderId(order.getOrderId());
orderDto.setUserAddress(order.getUserAddress());
orderDto.setUserDestination(order.getUserDestination());
orderDto.setUserId(order.getUser().getUserId());
orderDto.setCarId(order.getCar().getCarId());
return orderDto;
}
private Order mergeDtoIntoAggregate(OrderDto orderDto){
Order order = new Order();
order.setOrderId(orderDto.getOrderId());
order.setOrderCost(orderDto.getOrderCost());
order.setUserAddress(orderDto.getUserAddress());
order.setUserDestination(orderDto.getUserDestination());
order.setOrderDate(orderDto.getOrderDate());
return order;
}
}
So I used dao in assembler and I want to know can I do that? Thanks.