0

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.

DozezQuest
  • 179
  • 7

0 Answers0