I have several entities but there are three entities that have relationship on each other(Car,CarCategory,Order)
Car entity :
@Entity
@Table(name = "car_info")
@Getter
@Setter
public class Car implements Serializable {
private static final long serialVersionUID = -1473879605284728654L;
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Id
@Column(name = "carId", nullable = false)
private Long carId;
@Column(name = "numOfPas")
private int numOfPas;
@Column(name = "carState")
private String carState;
@Column(name = "carName", length = 25)
private String carName;
@Column(name = "carImage")
@Lob
private byte[] carImage;
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "carCategory")
private CarCategory carCategory;
@OneToMany(mappedBy = "car", 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;
Car car = (Car) o;
return Objects.equals(getCarId(), car.getCarId());
}
@Override
public int hashCode() {
return Objects.hash(getCarId());
}
@Override
public String toString() {
final StringBuilder sb = new StringBuilder("Car{");
sb.append("carId=").append(carId);
sb.append(", numOfPas=").append(numOfPas);
sb.append(", carState='").append(carState).append('\'');
sb.append(", carName='").append(carName).append('\'');
sb.append('}');
return sb.toString();
}
}
CarCategory entity :
@Entity
@Table(name = "car_category")
@Getter
@Setter
public class CarCategory implements Serializable {
private static final long serialVersionUID = -4179236910442782235L;
@Column(name = "carCategoryName", nullable = false, length = 15)
@Id
private String carCategoryName;
@Column(name = "costPerOneKilometer")
private double costPerOneKilometer;
@Column(name = "discountPerPrice")
private double discountPerPrice;
@Column(name = "carCategoryImage")
@Lob
private byte[] carCategoryImage;
@OneToMany(mappedBy = "carCategory", cascade = CascadeType.ALL, orphanRemoval = true)
private List<Car> cars = new ArrayList<>();
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
CarCategory that = (CarCategory) o;
return Objects.equals(getCarCategoryName(), that.getCarCategoryName());
}
@Override
public int hashCode() {
return Objects.hash(getCarCategoryName());
}
}
Order entity :
@Entity
@Table(name = "user_order", indexes = {
@Index(name = "idx_order_userid_carid_unq", columnList = "userId, carId", unique = true)
})
@Getter
@Setter
public class Order implements Serializable {
private static final long serialVersionUID = -4577879200654802752L;
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Id
@Column(name = "orderId", nullable = false)
private Long orderId;
@Column(name = "userAddress", length = 60)
private String userAddress;
@Column(name = "userDestination", length = 60)
private String userDestination;
@Column(name = "orderCost")
private double orderCost;
@Column(name = "orderDate", columnDefinition = "DATETIME")
private LocalDateTime orderDate;
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "userId")
private User user;
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "carId")
private Car car;
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Order order = (Order) o;
return Objects.equals(getOrderId(), order.getOrderId());
}
@Override
public int hashCode() {
return Objects.hash(getOrderId());
}
@Override
public String toString() {
final StringBuilder sb = new StringBuilder("Order{");
sb.append("orderId=").append(orderId);
sb.append(", userAddress='").append(userAddress).append('\'');
sb.append(", userDestination='").append(userDestination).append('\'');
sb.append(", orderCost=").append(orderCost);
sb.append(", orderDate=").append(orderDate);
sb.append('}');
return sb.toString();
}
}
As you can see Order has relationship to car and carCategory has relationship to car
So for converting to dto I have this assembler which will be used in service layer
Assembler interface :
public interface Assembler<E,D >{
D mergeAggregateIntoDto(E entity);
E mergeDtoIntoAggregate(D dto);
}
CarCategoryAssembler :
@Service
public class CarCategoryAssembler implements Assembler<CarCategory, CarCategoryDto> {
@Override
public CarCategoryDto mergeAggregateIntoDto(CarCategory entity) {
CarCategoryDto carCategoryDto = new CarCategoryDto();
carCategoryDto.setCarCategoryName(entity.getCarCategoryName());
carCategoryDto.setCostPerOneKilometer(entity.getCostPerOneKilometer());
carCategoryDto.setCarCategoryImage(entity.getCarCategoryImage());
carCategoryDto.setDiscountPerPrice(entity.getDiscountPerPrice());
carCategoryDto.setCars(entity.getCars().stream().map(this::mergeAggregateIntoDto).collect(Collectors.toList()));
return carCategoryDto;
}
@Override
public CarCategory mergeDtoIntoAggregate(CarCategoryDto dto) {
CarCategory carCategory = new CarCategory();
carCategory.setCarCategoryImage(dto.getCarCategoryImage());
carCategory.setCarCategoryName(dto.getCarCategoryName());
carCategory.setDiscountPerPrice(dto.getDiscountPerPrice());
carCategory.setCostPerOneKilometer(dto.getCostPerOneKilometer());
carCategory.setCars(dto.getCars().stream().map(carDto -> {
Car car =mergeDtoIntoAggregate(carDto);
car.setCarCategory(carCategory);
return car;
}).collect(Collectors.toList()));
return carCategory;
}
private CarDto mergeAggregateIntoDto(Car car){
CarDto carDto = new CarDto();
carDto.setCarCategory(car.getCarCategory().getCarCategoryName());
carDto.setCarId(car.getCarId());
carDto.setCarImage(car.getCarImage());
carDto.setCarState(car.getCarState());
carDto.setNumOfPas(car.getNumOfPas());
carDto.setCarName(car.getCarName());
return carDto;
}
private Car mergeDtoIntoAggregate(CarDto dto) {
Car car = new Car();
car.setCarId(dto.getCarId());
car.setCarImage(dto.getCarImage());
car.setCarName(dto.getCarName());
car.setCarState(dto.getCarState());
car.setNumOfPas(dto.getNumOfPas());
return car;
}
}
So if I need OrderAssembler I will have duplicate code when I'm converting Car to Car Dto and back. So how can I prevent duplicate code? Thanks.