MSA 개인 과제 실습
일단 구성해야 할 아키텍처는 다음과 같다

먼저 기본 프로젝트를 모두 생성하고, 유레카 서버에 정상 등록되는지 확인했다

본격 개발 시작
진행하면서 어려움을 겪은 부분을 정리해보았다
RDB로 PostgreSQL을 사용하는데, 이미 DB가 생성된 후라 DB를 드랍하거나 설정을 바꿔야 했다.
그냥 설정을 바꿨다.
그냥 아무런 조건 없이 들어가있는 bigint

수정 후

드디어 상품 하나 등록했다 ㅋ ㅋ ㅋ ㅋ ㅋ
진짜 모든걸 다 해봤다.
디버그도 엄청 찍고, 설정도 엄청 세세하게 해보고 별짓을 다했는데..
네트워크 문제도 아니고 로직도 멀쩡하고 유레카도 잘 떴는데..
@FeignClient(name="product", fallback = ProductClientFallback.class)
public interface ProductClient {
@GetMapping("/products/validate")
ResponseDto validateProducts(@RequestParam("productIds") List<Long> productIds);
}
그냥 @RequestParam List<Long> productIds으로 보내던 걸 이름을 명시하고 해결됐다.
눈물..
postgreSQL을 쓰는데 예약어인 몇몇가지는 테이블명으로 쓰지 않는 게 좋다.
order라던가.. user라던가..
그냥 복수형으로 테이블명을 매핑해주면서 해결
분명 order-product-order로 spans가 3이 나와야 하는 요청인데 자꾸 order 하나만 잡혔다.
이전에도 겪었던 문제인데 이번에도 똑같은 실수를 했다.
의존성 누락...
제대로 추가해주었다.
implementation 'org.springframework.boot:spring-boot-starter-actuator'
implementation 'io.micrometer:micrometer-tracing-bridge-brave'
implementation 'io.github.openfeign:feign-micrometer'
implementation 'io.zipkin.reporter2:zipkin-reporter-brave'

public class Order {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(updatable = false, nullable = false)
private Long id;
@ElementCollection
@CollectionTable(name = "order_product_ids", joinColumns = @JoinColumn(name = "order_id"))
private List<Long> productIds;
}
Order의 productIds 필드를 ElementCollection으로 해두었는데 캐싱 시 lazy initialization 상태에서 직렬화되려다 실패함.
Hibernate가 Session 밖에서 lazy-loaded 필드를 초기화하려고 할 때 발생하는 문제
해결
// 주문 단건 조회
@Cacheable(cacheNames = "orderCache", key="#orderId")
public ResponseDto getOneOrder(Long orderId) {
Order order = orderRepository.findById(orderId).orElse(null);
if(order == null) {
return new ResponseDto(ResponseDto.FAILURE, "해당하는 주문이 없습니다", null);
}
OrderResponse orderResponse = OrderResponse.builder()
.orderId(order.getId())
.productIds(order.getProductIds())
.build();
return new ResponseDto(ResponseDto.SUCCESS, "주문 조회 성공", orderResponse);
}
요랬는뎅
// 주문 단건 조회
@Cacheable(cacheNames = "orderCache", key="#orderId")
public ResponseDto getOneOrder(Long orderId) {
Order order = orderRepository.findById(orderId).orElse(null);
if(order == null) {
return new ResponseDto(ResponseDto.FAILURE, "해당하는 주문이 없습니다", null);
}
OrderResponse orderResponse = OrderResponse.builder()
.orderId(order.getId())
.productIds(new ArrayList<>(order.getProductIds()))
.build();
return new ResponseDto(ResponseDto.SUCCESS, "주문 조회 성공", orderResponse);
}
요래됐슴당
흑흑
문제상황
@ElementCollection과 같은 관계 필드가 기본적으로 Lazy Loaded로 설정되어 있다면, 해당 필드의 데이터는 실제로 접근하기 전까지 초기화되지 않는다LazyInitializationException이 발생한다LazyInitializationException이 발생그게 뭐가 문젠데
한마디로
세션이 닫혀있는데도 Hibernate의 지연 로딩 필드에 접근하려고 했기 때문에 문제 발생