[6]. MailMilkDashBoard 순환참조 발생 다시 DTO 변환하기

6236 단어 SpringbootSpringboot

이전 글의 Entity <-> DTO 변환에 엔티티 자체를 DTO로 변환해서 반환 했더니..
참조를 위해 만들어놨던 list에 순환참조가 일어났다.

문제는 엔티티자체를 반환하는 리스트가 문제였다. 그리고 나는 customer에 정보를 다 들고 올게 아니였고 이메일만 필요 했었다. 그래서 DTO를 하나 새로 만들고 그거에 맞춰줬다.

일단 먼저 나는 고객이 우유리스트를 불러 올때 customer랑 delivery정보는 필요 없었다.
그 고객이 먹는 우유의 리스트만 알고 싶었기 때문이다.


@Getter
@NoArgsConstructor
public class Milk {

    @Builder
    public Milk(int id, String apartmentName, int apartmentHouseNumber1,
                int apartmentHouseNumber2, String milkManufacturer, String milkName,
                int milkCount, String weekDate
    ) {
        this.id = id;
        this.apartmentName = apartmentName;
        this.apartmentHouseNumber1 = apartmentHouseNumber1;
        this.apartmentHouseNumber2 = apartmentHouseNumber2;
        this.milkManufacturer = milkManufacturer;
        this.milkName = milkName;
        this.milkCount = milkCount;
        this.weekDate = weekDate;
    }

    private int id;

    // 아파트 이름
    private String apartmentName;

    // 아파트 동 수
    private int apartmentHouseNumber1;

    // 아파트 호 수
    private int apartmentHouseNumber2;

    // 우유 대리점 이름
    private String milkManufacturer;

    // 우유 이름
    private String milkName;

    // 우유 수량
    private int milkCount;

    // 먹는 요일
    private String weekDate;

    static List<Milk> toList(List<MilkEntity> milkEntities){
        List<Milk> milks = new ArrayList<>();
        milkEntities.forEach(milkEntity -> {
            milks.add(new Milk(milkEntity.getId(), milkEntity.getApartmentName(), milkEntity.getApartmentHouseNumber1(),
                    milkEntity.getApartmentHouseNumber2(), milkEntity.getMilkManufacturer(), milkEntity.getMilkName(),
                    milkEntity.getMilkCount(), milkEntity.getWeekDate()));
        });
        return milks;
    }
}

@NoArgsConstructor
@Getter
public class CustomerDTO {

    public CustomerDTO(CustomerEntity customer) {
        this.email = customer.getEmail();
        this.password = customer.getPassword();
        this.phoneNumber = customer.getPhoneNumber();
        this.contractPeriod = customer.getContractPeriod();
        this.delinquencyPeriod = customer.getDelinquencyPeriod();
        this.joinDate = customer.getJoinDate();
        this.withdrawalDate = customer.getWithdrawalDate();
        this.note = customer.getNote();
        this.milks = Milk.toList(customer.getMilkDTOS());
    }

    //고객 아이디
    private String email;

    //비밀번호
    private String password;

    //핸드폰 번호
    private String phoneNumber;

    //계약기간
    private Date contractPeriod;

    //연체기간
    private Date delinquencyPeriod;

    //가입날짜
    private Date joinDate;

    //탈퇴날짜
    private Date withdrawalDate;

    //비고
    private String note;

    private List<Milk> milks = new ArrayList<>();

}

    CustomerDTO findByEmail(String email);

이렇게 있을 때 Milk는 List에 불러오는 MilkEntity를 DTO 작성했다.

      static List<Milk> toList(List<MilkEntity> milkEntities){
        List<Milk> milks = new ArrayList<>();
        milkEntities.forEach(milkEntity -> {
            milks.add(new Milk(milkEntity.getId(), milkEntity.getApartmentName(), milkEntity.getApartmentHouseNumber1(),
                    milkEntity.getApartmentHouseNumber2(), milkEntity.getMilkManufacturer(), milkEntity.getMilkName(),
                    milkEntity.getMilkCount(), milkEntity.getWeekDate()));

        });
        return milks;
    }

필요한 정보만 저장하는 List에 데이터를 넣고 반환한다.

1. CustomerDTO customerDTO  = customerRepository.findByEmail("[email protected]");

2. public CustomerDTO(CustomerEntity customer) {
      this.milks = Milk.toList(customer.getMilkDTOS());
  }


1번을 보면 findByEmail()의 반환값은 CustomerEntity인데 그걸 CustomerDTO에서 받아서 재정의한다. ( findById()를 보여준 이유는 이메일로 조회를 하면 CustomerEntity가 넘어온다는것이다. )

2번을 보면 Milk.toList()함수가 있는데 Milk클래스에 static으로 선언한것이다.
MilkEntity로 넘어오는 리스트를 Milk로 만들어서 반환한다. 위쪽 static 부분을 보면 될것이다.

고객정보를 불러 왔을 때 우유정보에서는 내가 원하는 정보만 불러오고 순환참조도 해결했다.

이 순환참조는 배달원정보에서도 발생 했는데 수정했다.

참고로 전화번호는 막 누른것이다..이 프로젝트에서 사용하는 데이터는 이메일 빼고는 아무것도 아닌다.

하지만 한 곳이 더 남았다. 바로 우유엔티티에서 우유정보를 불러올 때 순환참조가 발생한다.
사용자 이메일로 우유정보를 검색했을 때.. 우유 정보는..
고객 이메일, 배달원 이메일, 나머지 우유정보들이다.

기존에는 엔티티를 참조하고 있어서 엔티티를 저장했는데 그러다보니 모든곳에서 사용하기만 하면 순환참조가 발생하는것이다. 그래서 내가 필요한건 고객의 이메일. 그래서 고객을 참조하던 엔티티를 빼고 String email을 넣고 넘어오는 엔티티에서 .getCustomer().getEmail()로
이메일을 지정해줬다. 이게 필요한 이유는 우유레포지터리에서 findAll을 통해서 다 불러올건데
구분하기 위해서 필요하다. 단지 고객이 어떤 우유를 먹고 싶은지 보고 싶으면 customer 레포지터리에서 findByEmail()하면 된다.

좋은 웹페이지 즐겨찾기