순환 참조 에러

2023. 10. 31. 15:04
728x90

1. findall() 메소드를 사용해서 JSON 형태로 전체 Owner 목록 조회를 하려고 했다. 

결과를 봤더니 (???) 띠용~~~~~~

무한......으로 계속 나와서 왔다리 갔다리 나오면서 

StackOverFlow 에러가 나온다. 

 

이유는 

Owner 클래스에서는 pets 객체를 불러들이고

Pet 클래스에서는 owner 객체를 불러들인다.. 그러면 얘가 쟤를 부르고 쟤가 얘를 부르고 왔다갔다 계속 서로를 불러들인다...

이 것을 멈추기 위해서는 여러가지 방법이 있는데 나는 DTO를 만들어주는 방법을 사용했다. 

 

데이터를 DTO라는 껍데기에 넣어주기로 했다.  "응답용 객체"로 만들어주기.

 

1. OwnerResponse 객체 클래스를 생성한다. (DTO)

여기에 Owner의 정보를 OwnerResponse에다가 부어주는 것!!

일단 Pet 부분은 무시하기로 하고,,,,, OwnerResponse를 객체로 findAll()을 해보자.

 

1) Owner의 필드들 다 갖고와서 

2) 생성자 생성하기

3) 정적(static) 팩토리 메서드를 만들어본다. 

즉 Owner 객체를 OwnerResponse에 부어주는 과정임.

owner.get~~~() 메소드 활용해서~~~

 

그리고 return값은 new OwnerResponse(...)로 리턴해주면 

이제 이 response 객체를 Controller에서 활용해보자.

package dev.spring.petclinic.DTO;

// Owner에 대한 응답용 객체(Response)로 사용될 클래스
import dev.spring.petclinic.model.Owner;
import dev.spring.petclinic.model.Pet;
import lombok.Getter;
import lombok.ToString;

import java.time.LocalDate;
import java.util.List;
import java.util.stream.Collectors;

@Getter
@ToString
public class OwnerResponse {
    private Long id;
    private String firstName;
    private String lastName;
    private String address;
    private String city;
    private String telephone;
    private List<PetResponse> pets; //petResponse객체로 리스트를 만들어줌.

    // 생성자 생성
    private OwnerResponse(Long id, String firstName, String lastName, String address, String city, String telephone, List<PetResponse> pets) {
        this.id = id;
        this.firstName = firstName;
        this.lastName = lastName;
        this.address = address;
        this.city = city;
        this.telephone = telephone;
        this.pets = pets;
    }

    // 이펙티브 자바 item - 정적(static) 팩토리 메서드
    public static OwnerResponse from (Owner owner) {
        final Long id = owner.getId();
        final String firstName = owner.getFirstName();
        final String lastName = owner.getLastName();
        final String address = owner.getAddress();
        final String city = owner.getCity();
        final String telephone = owner.getTelephone();
        // todo : pet 데이터 맵핑
        final List<PetResponse> petResponses = owner.getPets().stream().map(PetResponse::from)
                .collect(Collectors.toList());

        return new OwnerResponse(id, firstName, lastName, address, city, telephone, petResponses);
    }
}

 

2. OwnerRestController에서 메소드구현

1) @RestController 애너테이션 (@Controller, @ResponseBody)

2) @RequestMapping("/api/owners") 로 오는 모든 요청 받도록

3) @AllArgsConstructor 생성자

4) OwnerService 객체 필드 생성

5) @GetMapping 으로 list 메소드를 만들어주는데 이때 반환값을 "OwnerResponse"의 리스트로 받아준다. 

 

그리고 findAll()메소드로 Owner 리스트를 받아오고 

이것을.stream().map(OwnerResponse::from).collect(Collectors.toList())로 리턴해주면 OwnerResponse객체의 리스트값으로 반환 가능!!!!

* stream() 리스트를 스트림으로 변환.

* map(OwnerResponse::from) : Owner 객체를 OwnerResponse 객체로 변환 (각 요소를 변환)

* collectors.toList() : 스트림 요소를 리스트로 수집

@GetMapping
    public List<OwnerResponse> listsOwners(){
        //service.findAll() 호출 및 반환
        List<Owner> owners = ownerService.findAll();

        List<OwnerResponse> ownerList = owners.stream().map(OwnerResponse::from)
                .collect(Collectors.toList());
                
        return ownerList;
    }

 

이 메소드를 풀어쓰면..

1) OwnerResponse 객체를 담을 ArrayList(owenerList) 생성

2) Owner객체 담은 List인 owners의 하나하나 반복문을 돈다.

3) owner1에 담긴 것들을 OwnerResponse 객체로 변환!!!! 하여 from 변수에 할당

4) 변환된 객체 from을 ownerList에 추가 - 반복문이 끝날 때까지.

        // 풀어쓰면
        List<OwnerResponse> ownerList = new ArrayList<>();
        for (Owner owner1 : owners) {
            OwnerResponse from = OwnerResponse.from(owner1);
            ownerList.add(from);
        }
@GetMapping
    public List<OwnerResponse> listsOwners(){
        //service.findAll() 호출 및 반환
        List<Owner> owners = ownerService.findAll();

        List<OwnerResponse> ownerList = owners.stream().map(OwnerResponse::from)
                .collect(Collectors.toList());
                
        return ownerList;
    }

 

이렇게 하면 ~~~~?

요렇게 JSON 형태로 잘 나온다... 예쓰~~~~~~~!!

 

728x90

BELATED ARTICLES

more