본문 바로가기

독서60

Part1 더 큰 그림 [하] Chapter3 단위 테스트 구조 3.1 단위 테스트를 구성하는 방법(1) AAA 패턴 사용using System;using Xunit;namespace Book.Chapter3.Listing1{ public class CalculatorTests { [Fact] public void Sum_of_two_numbers() { // Arrange double first = 10; double second = 20; var calculator = new Calculator(); // Act double result = calculator.Sum.. 2024. 12. 17.
Part1 더 큰 그림 [상] Chapter 1 : 단위 테스트의 목표이 책에서 어떤 단위 테스트 기술이 좋은지 구별하는 데 도움이 될 것이다. 테스트에 대한 비용 편익 분석 방법을 배우고, 특정 상황에서 적절한 테스트 기술을 배울 수 있다. 공통적인 안티 패턴을  피하는 방법도 배운다. 기본부터 시작해 볼 예정이고, 테스트 작성과 유지 보수의 목표를 설명하여 테스트 스위트를 잘 작성할 수 있는 방법을 소개한다.  1.1 단위 테스트 현황논쟁은 '단위 테스트를 작성해야 하는가'에서 '좋은 단위 테스트를 작성하는 것은 어떤 의미인가'로 바뀌었다. 이상적인 단위 테스트에 대해 정확하고 과학적인 정의를 다룬다. 기업용 애플리케이션이란 조직 내부 프로세스를 자동화하거나 지원하기 위한 응용프로그램이다. 일반적으로 아래와 같은 특성이 있다.- .. 2024. 12. 15.
10~11장 이벤트, CQRS ( 完 ) 10.1 시스템 간 강결합 문제쇼핑몰에서 구매를 취소하면 환불을 처리해야 한다. 이때 환불 기능을 실행하는 주체는 주문 도메인 엔티티가 될 수 있다. 보통 결제 시스템은 외부에 존재하므로 RefundService는 외부에 있는 결제 시스템이 제공하는 환불 서비스를 호출한다. 2가지 문제가 발생할 수 있다. 1) 외부 서비스가 정상이 아닌 경우 트랜잭션 처리를 어떻게 해야 할지 애매하다. 외부의 환불 서비스를 실행하는 과정에서 익셉션이 발생하면 환불에 실패했으므로 주문 취소 트랜잭션을 롤백하는 것이 맞아 보인다. 하지만 반드시 트랜잭션을 롤백 해야 하는 것은 아니다. 주문은 취소 상태로 변경하고 환불만 나중에 다시 시도하는 방식으로 처리할 수도 있다. 2) 두 번째 문제는 성능에 관한 것이다. 환불을 처리.. 2024. 12. 8.
9장 도메인 모델과 바운디드 컨텍스트 9.1 도메인 모델과 경계논리적으로 같은 존재처럼 보이지만 하위 도메인에 따라 다른 용어를 사용하는 경우도 있고, 한 개인 상품이 다른 곳에서는 여러 개 존재할 수 있다. 하위 도메인마다 같은 용어라도 의미가 다르고, 같은 대상이라도 지칭하는 용어가 다를 수 있기 때문에 한 개의 모델로 모든 하위 도메인을 표현하려는 시도는 올바른 방법이 아니며 표현할 수도 없다. 하위 도메인마다 사용하는 용어가 달라서 올바른 도메인 모델을 개발하려면 하위 도메인 모델을 만들어야 한다. 각 모델은 명시적으로 구분되는 경계를 가져서 섞이지 않도록 해야 한다. 모델은 특정한 컨텍스트(문맥) 하에서 완전한 의미를 갖는다. 같은 제품이라도 카탈로그 컨텍스트와 재고 컨텍스트에서 의미가 서로 다르다. 이렇게 구분되는 경계를 갖는 컨.. 2024. 12. 5.
8장 애그리거트 트랜잭션 관리 8.1 애그리거트와 트랜잭션DBMS가 지원하는 트랜잭션과 함께 애그리거트를 위한 추가적인 기법이 필요하다. 대표적인 트랜잭션 처리 방식에는 선점 잠금과 비선점 잠금 방식이 있는데 이를 살펴보자.  8.2 선점 잠금선점 잠금은 먼저 애그리거트를 구한 스레드가 애그리거트 사용이 끝날 때까지 다른 스레드가 해당 애그리거트를 수정하지 못하게 막는 방식이다. 스레드1이 애그리거트를 구한 뒤 이어서 스레드2가 같은 애그리거트를 구하고 있다. 스레드 2는 스레드1이 애그리거트에 대한 잠금을 해제할 때까지 블로킹된다. 한 스레드가 애그리거트를 구하고 수정하는 동안 다른 스레드가 수정할 수 없으므로 동시에 애그리거트를 수정할 때 발생하는 데이터 충돌 문제를 해소할 수 있다. 선점 잠금은 보통 DBMS가 제공하는 행단위 .. 2024. 12. 5.
6장 응용 서비스와 표현 영역 6.1 표현 영역과 응용 영역1장부터 5장까지 도메인의 구성 요소, JPA를 이용한 리포지터리 구현 방법을 알아봤다. 도메인 영역을 잘 만들어도, 도메인이 제 기능을 하려면 사용자 도메인을 연결해주는 매개체가 필요하다. 응용 영역과 표현 영역이 사용자와 도메인을 연결해주는 매개체 역할을 한다. 표현 영역은 사용자의 요청을 해석한다. 요청을 받은 표현 영역은 URL, 요청 파라미터, 쿠키, 헤더 등 이용해서 사용자가 실행하고 싶은 기능을 판별하고 그 기능을 제공하는 응용 서비스를 실행한다. 실제 사용자가 원하는 기능을 제공하는 것은 응용 영역에 위치한 서비스다. 응용 서비스의 메서드가 요구하는 파라미터와 표현 영역이 사용자로부터 전달받은 데이터는 형식이 일치하지 않기 때문에 표현 영역은 응용 서비스가 요구.. 2024. 12. 3.
5장 스프링 데이터 JPA를 이용한 조회 기능 5.1 시작에 앞서시작에 앞서 CQRS 알고가자. 명령(command) 모델과, 조회(query) 모델을 분리하는 패턴이다. 명령 모델은 상태를 변경하는 기능을 구현할 때 사용하고, 조회 모델은 데이터를 조회하는 기능을 구현할 때 사용한다. 엔티티, 애그리거트, 리포지터리 등 앞에서 살펴본 모델은 주문 취소, 배송지 변경과 같이 상태를 변경할 때 주로 사용된다. 즉 도메인 모델은 주문 취소, 배송지 변경과 같이 상태를 변경할 때 주로 사용된다. 명령 모델로 주로 사용된다. 반면에 이 장에서 설명할 정렬, 페이징, 검색 조건 지정과 같은 기능은 조회 기능에 사용된다. 즉 이 장에서 살펴볼 구현 방법은 조회 모델을 구현할 때 주로 사용한다.  5.2 검색을 위한 스펙목록 조회와 같은 기능은 다양한 검색 조건.. 2024. 12. 2.
4장 리포지터리와 모델 구현 4.1.1 모듈 위치리포지터리 인터페이스는 애그리거트와 같이 도메인 영역에 속하고, 리포지터리를 구현한 클래스는 인프라스트럭처 영역에 속한다. 가능하면 리포지터리 구현 클래스를 인프라스트럭처 영역에 위치시켜서 인프라스트럭처에 대한 의존을 낮춰야 한다.   4.1.2 리포지터리 기본 기능 구현리포지터리가 제공하는 기본 기능은 다음 두 가지다.1) ID로 애그리거트 조회하기2) 에그리거트 저장하기 인터페이스는 애그리거트 루트를 기준으로 작성한다. 루트 엔티티인 Order를 기준으로 리포지터리 인터페이스를 작성한다. 애그리거트를 조회하는 기능의 이름을 지을 때, 널리 사용되는 규칙은 'findBy프로퍼티이름(프로퍼티 값)' 형식을 사용하는 것이다. findById()는 ID에 해당하는 애그리거트가 존재하면 O.. 2024. 12. 1.
3장 애그리거트 3.1 애그리거트도메인 객체 모델이 복잡해지면 개별 구성요소 위주로 모델을 이해하게 되고 전반적인 구조나 큰 수준에서 도메인 간의 관계를 파악하기 어려워진다. 도메인 요소 간 관계를 파악하기 어렵다는 것은 코드를 변경하고 확장하는 것이 어려워진다는 것을 의미한다. 이를 해결할 수 있는 방법이 애그리거트이다. 일관성을 관리하는 기준이 될 수 있고, 모델을 이해하는 데 도움이 된다. 애그리거트는 관련된 모델을 하나로 모았기 때문에 한 애그리거트에 속한 객체는 유사하거나 동일한 라이프 사이클을 갖는다. 도메인 규칙에 따라 최초 주문 시점에 일부 객체를 만들 필요가 없는 경우도 있지만 애그리거트에 속한 구성요소는 대부분 함께 생성하고 함께 제거한다. 애그리거트는 경계를 갖는다. 한 애그리거트에 속한 객체는 다른.. 2024. 11. 29.
2장 아키텍처 개요 2.1 네 개의 영역'표현', '응용', '도메인', '인프라스트럭처'는 아키텍처를 설계할 때 출현하는 전형적인 네 가지 영역이다. 네 영역 중 표현 영역은 사용자의 요청을 받아 응용 영역에 전달하고 응용 영역의 처리 결과를 다시 사용자에게 보여주는 역할을 한다. 웹 애플리케이션을 개발할 때 많이 사용하는 스프링 MVC 프레임워크가 표현 영역을 위한 기술에 해당한다. 웹 애플리케이션에서 표현 영역의 사용자는 웹 브라우저를 사용하는 사람일 수 있고, REST API를 호출하는 외부 시스템일 수 있다. 표현 영역을 통해 사용자의 요청을 전달받는 응용 영역은 시스템이 사용자에게 제공해야 할 기능을 구현하는데 '주문 등록', '주문 취소', '상품 상세 조회' 같은 기능 구현을 예로 들 수 있다. 응용 영역은 .. 2024. 11. 28.
1장 도메인 모델 시작하기 1.1 도메인이란?개발자 입장에서 바라보면 온라인 서점은 구현해야 할 소프트웨어의 대상이 된다. 온라인 서점은 책을 판매하는 데 필요한 상품 조회, 구매, 결제, 배송 추적 등 기능을 제공해야 한다. 이때 온라인 서점은 소프트웨어로 해결하고자 하는 문제 영역, 즉 도메인에 해당한다. 예로 온라인 서점 도메인은 몇 개의 하위 도메인으로 나눌 수 있다. 하위 도메인을 어떻게 구성할지 여부는 상황에 따라 달라진다.   1.2 도메인 전문가와 개발자 간 지식 공유코딩에 앞서 요구사항을 올바르게 이해하는 것이 중요하다. 간단한 방법으로 개발자와 전문가가 직접 대화하는 것이다. 도메인 전문가만큼은 아니겠지만 이해관계자와 개발자도 도메인 지식을 갖춰야 한다. 전문가나 관련자가 요구한 내용이 항상 올바른 것은 아니며,.. 2024. 11. 27.
5장 반복문 정리중 2024. 11. 24.
4장 집약과 자르기 정리중 2024. 11. 23.
3장 SQL의 조건 분기 2장에서는 조건 분기를 할 때 CASE 식을 설명했죠. 사실 이외에도 사용할 수 있는 구문이 있습니다. 바로 UNION입니다. 하지만 이는 좋은 일이 아닙니다. UNION은 조건 분기를 위해 만들어진 것이 아니기 때문입니다. 많은 사람들이 어떻게 작동할지 쉽게 예측할 수 있다는 이유로 사용하는데, 이번 장에서는 UNION을 사용하지 않고 CASE 방식이라는 SQL의 원래 조건 분기 기능을 몸에 밸 수 있게 하는 것이 목표입니다.  8강 UNION을 사용한 쓸데없이 긴 표현UNION 방식은 성능적인 측면에서 단점을 가지고 있습니다. 외부적으로는 하나의 SQL 구문을 실행하는 것처럼 보이지만, 내부적으로는 여러 개의 SELECT 구문을 실행하는 실행 계획으로 해석되기 때문이죠. 테이블에 접근하는 횟수가 많아.. 2024. 11. 22.
2장 SQL 기초 데이터베이스 이용 시 핵심이 되는 처리가 바로 검색입니다. 데이터가 저장되어 있는 테이블에서 필요한 데이터를 뽑아내는 것인데, 질의(query)라던지 추출(retrieve)이라고 부릅니다. 이를 SELECT 구문이라고 부르고, 문자 그대로 선택한다는 것인데요. SELECT 구문은 2개의 부분으로 구성되어 있습니다. 6장 SELECT 구문6.1 SELECT 구와 FROM 구첫 번째는 SELECT 뒤에 나열되어 있는 부분으로, SELECT 구라고 부릅니다. 데이터베이스에서 검색할 때 반드시 입력되어야 하는 부분입니다. 테이블이 갖고 있는 필드라면 쉼표로 연결해 여러 개 쓸 수 있습니다. 두 번째 부분은 'FROM [테이블 이름]'으로 FROM 구라고 부르며, 데이터를 선택할 대상 테이블을 지정합니다. 반드시.. 2024. 11. 21.
1장 DBMS 아키텍처 이 책의 목적은 성능 좋은 SQL을 쓰는 방법, 특히 대량의 데이터를 처리하는 SQL의 성능을 향상시키는 방법을 이해하는 것입니다. RDB와 SQL은 '사용자가 직관적으로 처리할 수 있는 인터페이스'와, '대용량 데이터의 효율적 처리'라는 상반된 명제 사이에 있는 미들웨어입니다. 데이터가 쌓이는 속도와 데이터에 접근하는 속도가 달라지면서 데이터베이스에 많은 부하가 걸리기 시작했습니다. 2010년 전후로 그러한 빅데이터를 처리하기 위한 여러 방법이 있습니다. 예로, Nosql. 왜 2010년에는 SQL로 많은 양의 데이터를 처리할 수 없다 생각했을까요? 가장 큰 문제는 많은 개발자가 SQL을 제대로 사용하지 못하기 때문입니다.  1강 DBMS 아키텍처 개요RDB 제품이 많은데, 전부 관계 모델이라는 수학적.. 2024. 11. 20.
17. 테스트와 개발 방법론 完 TDD는 소프트웨어 개발 방법론 중 하나로, 개발자가 코드를 작성하기 전에 해당 코드의 테스트 케이스를 먼저 작성하게 한 후 해당 테스트를 통과할 수 있는 코드를 작성하는 방식으로 소프트웨어를 개발합니다. 여기서 파생한 개념으로 BDD가 있습니다. BDD는 소프트웨어 개발 과정에서 비즈니스 요구사항과 소프트웨어의 행동을 강조하는 개발 방법론입니다. 개발자는 비즈니스 의도를 명확하게 이해해야 하고, 스펙을 테스트 가능한 형태로 작성할 수 있어야 합니다. 개발팀과 비즈니스팀 간의 빈번한 의사소통 강조, 테스트 케이스 명세 시 Given-When-Then 같은 자연어로 구성된 시나리오를 사용하는 것을 권장합니다. TDD, BDD는 코드의 안정성과 유연성을 높여 소프트웨어의 품질을 향상할 수 있는 가장 현대적인.. 2024. 11. 20.
16장 테스트와 설계 테스트와 소프트웨어 설계는 긴밀한 상관관계를 맺습니다. 상호보완적이죠. 당연한 이유는 좋은 소프트웨어 설계와 테스트가 추구하는 목표가 일정 부분 같기 때문입니다. 즉, 테스트가 추구하는 가치와 좋은 설계가 추구하는 가치에 일정 부분 교집합이 있는 것입니다. 좋은 설계는 시스템이 모듈로 분해되고, 각 모듈이 독립적으로 개발될 수 있게 하는 것을 추구합니다. 유연하게 확장될 수 있는 것을 추구하죠. 확장할 수 있는 시스템이란 다양한 기능을 제공할 수 있다는 의미도 있지만, 다양한 환경에도 이식할 수 있는 시스템이라는 뜻이기도 하죠.  16.1 테스트와 SRP, ISPUserService 컴포넌트의 login, Register 메서드를 분리하는 것이 맞을까요? SRP 관점에서 컴포넌트를 사용하려는 주체가 시스.. 2024. 11. 19.
15. 테스트 가능성 12장 '자동 테스트'에서는 테스트가 필요한 이유가 무엇인지 얘기했습니다. 테스트가 중요한 이유로 '회귀 버그 방지'였습니다. 하지만 실제로 테스트는 추가로 이점을 제공합니다. 예로, 테스트를 이용하면 전체 시스템의 품질을 향상할 수 있습니다. 테스트가 품질을 보증할 수 있어도, 품질을 개선해줄 수 없을 것 같다고 생각할 수 있죠. 테스트는 이미 만들어진 코드에 추가로 더 작성되는 요소이기 때문입니다. 테스트 자체는 수단에 불과합니다. 테스트를 '개발이 완료된 후 작성하는 것'이 아니라 '개발 전 미리 작성하는 것', '개발을 하면서 함께 작성하는 것'으로 보면 이야기가 달라지죠. 개발자는 어떻게 테스트를 작성하면 쉽게 작성할 수 있을지 고민함으로써 코드의 품질을 높일 수 있습니다. 테스트를 '좋은 설계.. 2024. 11. 18.
14. 테스트 대역 테스트 대역에서 말하는 대역은 대역폭 같은 것이 아닙니다. 말 그대로 영화에 나오는 스턴트맨, '대역' 그 자체를 의미하죠. 즉, 오롯이 테스트를 위해 만들어진 가짜 객체나 컴포넌트를 가리키는 용어입니다. 실제 객체를 대신해서 행동하고 실제 객체가 하지 못하는 일을 대신합니다. 예로 메서드를 호출한 결과로 제대로 된 상태 값이 반영됐는지만 확인하고 싶습니다. 테스트를 실행할 때마다 메일이 실제로 발송되지 않았으면 한다고 가정하죠. 이럴 때 테스트 대역을 사용할 수 있습니다. 메일을 발송하는 컴포넌트인 VerificationEmailSender 대역을 만들고 테스트할 때 UserService가 이를 사용하게 만든다고 생각해 봅시다. DummyVerificationEmailSender 컴포넌트가 대역처럼 동.. 2024. 11. 17.
[12-17 하] 12. 자동 테스트 & 13. 테스트 피라미드 소프트웨어 공학에서 말하는 테스트는 소프트웨어의 품질과 기능을 확인하고, 버그를 찾아내는 과정을 말합니다. 크게 2가지로 분류하는데, 수동 테스트와 자동 테스트가 있습니다. 수동 테스트는 테스트 담당자가 소프트웨어를 직접 실행해보고 각각의 기능을 평가하여 구현된 기능이 요구사항에 부합하는지 검증하는 과정을 말합니다. 사용자 관점에서 소프트웨어를 다양한 시나리오를 토대로 실행하여, 검증 과정에서 사용자 경험을 직접 평가할 수 있죠. 자동 테스트는 테스트 스크립트, 도구를 사용해 자동으로 테스트하는 과정을 말합니다.  12. 자동 테스트인수 테스트란 무엇일까요? 시스템이 비즈니스 요구사항을 만족해서 소유권을 넘기기 전에 수행하는 테스트 단계를 뜻합니다. 시스템을 인수하기 전에 시스템이 비즈니스 요구사항과 .. 2024. 11. 15.
10. 도메인 & 11. 알아두면 유용한 스프링 활용법 소프트웨어 공학에서 말하는 '도메인'은 애플리케이션이 해결하고자 하는 문제 영역을 의미합니다. 백엔드 개발자 입장에서 도메인은 어떻게 바라보는 것이 좋은지, 애플리케이션을 개발한다는 말이 왜 도메인을 개발한다는 말과 같은지, 애플리케이션의 본질은 스프링이나 JPA가 아니라 도메인이다라는 말이 왜 존재하는지 알아보죠. 10.1 소프트웨어 개발의 시작사업가 입장에서 소프트웨어 시스템을 만들게 되는 계기를 먼저 이해해보죠. 일반적으로 비즈니스는 '소프트웨어를 만들어야겠다'라는 전체로 시작되지 않기 때문이죠. 사용자가 겪는 문제를 해결하는 것이 비즈니스입니다. IT 사업가란 사람들이 겪는 문제를 분석, 솔루션 고안, 이를 소프트웨어로 구현하는 사람들이라고 볼 수 있습니다. 린(lean) : '군더더기 없는'이라.. 2024. 11. 13.
9. 모듈 9.1 모듈성모듈이란 무엇일까요? 소프트웨어 공학에서 모듈은 프로그램의 기본 구성 요소이면서 라이브러리를 포괄하는 조금 더 큰 규모의 용어입니다. 즉 모듈이란 라이브러리와 프로그램의 구성 요소 사이에 위치하는 개념입니다. 하지만 이는 좀 모호한데 더 구체적으로는 독립성과 은닉성을 만족하며 연관된 코드들의 묶음입니다.1) 독립성 : 모듈은 독립적이어야 한다.2) 은닉성 : 모듈의 사용자는 모듈의 내부 구현을 몰라도 된다. 공개된 인터페이스를 이용해 모듈과 통신한다. 이때 독립성과 은닉성 같은 특성을 모듈성이라고 부릅니다. 즉 연관된 코드 묶음은 모듈성을 만족할 때 모듈이 될 수 있습니다. 모듈 시스템이란 연관된 코드 묶음이 '모듈성'을 갖출 수 있게 도와주는 시스템적인 해결책입니다. 그래서 다음과 같은 기.. 2024. 11. 13.
7. 서비스 서비스의 역할은 크게 3가지 종류의 일을 해야 합니다.1) 도메인 객체를 불러옵니다.2) 도메인 객체나 도메인 서비스에 일을 위임합니다.3) 도메인 객체의 변경 사항을 저장합니다. 7.1 Manager스프링에서 서비스는 왜 서비스라고 부를까요? 컨트롤러는 '제어부', 리포지터리는 '저장소', 컴포넌트는 '구성 요소'입니다. 서비스는 '비즈니스 서비스를 처리하는 곳입니다'라는 답변은 충분한 답변이 되지 못합니다. @Service 애너테이션이 적힌 주석을 보면, 답이 나오죠.1) @Service는 에릭 에반스의 DDD에서 영감을 받아 만들어진 애너테이션입니다.2) 서비스는 J2EE 패턴 중 하나인 비즈니스 서비스 파사드처럼 사용될 수 있다. 스프링 서비스는 DDD에서 파생된 개념이라고 합니다. 이제 DDD를.. 2024. 11. 12.
8. 레이어드 아키텍처 8.1 레이어드 아키텍처의 최소 조건레이어드 아키텍처는 애플리케이션을 레이어로 나누고, 각 레이어에 역할을 정합니다. 꼭 유념해야 할 사실이 하나 있는데, 여러 개발자의 필요에 의해 발전된 아키텍처입니다. 레이어드 아키텍처에서 중요한 것은 레이어 유형을 외우고, 그에 맞게 컴포넌트를 배치 하는 것이 아니라 아래와 같은 사항을 지키는 것이죠.1) 레이어 구조를 사용한다.2) 레이어 간 의존 방향은 단방향으로 유지한다.3) 레이어 간 통신은 인접한 레이어에서만 이뤄지게 한다. 위 2), 3) 같은 제약 즉, 레이어 '구조'에 제약을 더했더니 '아키텍처'가 됐다는 의미입니다. 그래서 '아키텍처'가 뭘까요? 명확한 답은 없지만 아키텍트들이 아키텍처를 설명할 때 공통으로 말하는 내용을 취합해 아키텍처란 무엇인지를.. 2024. 11. 10.
[6-11 중] 6. 안티패턴 Spring framework는 자바 기반의 오픈 소스 애플리케이션 프레임워크로서 J2EE 환경에서 시스템 개발을 쉽게 하고 유지보수성을 높이기 위해 개발됐죠. 스프링 이전에 사용하던 J2EE의 EJB는 엔터프라이즈 환경에서 안정성과 확장성을 제공하는 훌륭한 기술 스택이었지만 그만큼 무겁고 사용하기 어려워 비효율적이었습니다. 더불어 EJB는 EJB의 핵심 기술인 컨테이너 기술이 EJB의 제공 업체마다 구현이 달랐고, 그로 인해 사용하는 프로그램 자체가 특정 Vendor의 기술에 종속되는 문제가 발생할 수 있었죠. 스프링은 이러한 한계와 극복을 달성하기 위해 개발됐습니다. 경량화된 구조, 간소화된 설정, 제어 역전, 자동화된 의존성 주입 등 기능을 제공함으로써 EJB 단점을 해결했죠. 하지만 누구나 쉽게 .. 2024. 11. 9.
5. 순환참조 5.1 순환참조  5.2 순환참조를 해결하는 방법순환 참조가 나쁘다는 것은 알았고, 어떻게 하면 해결할 수 있을까요? 가장 확실한 방법은 순환 참조 자체를 만들지 않는 것입니다.  5.2.1 불필요한 참조 제거불필요한 참조를 제거한다는 것은 양방향 참조가 꼭 필요한지 재고해 본다는 의미입니다. 꼭 필요하지 않은 참조를 제거하거나 필요에 따라 관계를 표현하긴 해야 한다면 한쪽이 다른 한쪽의 식별자를 갖고 있게 해서 간접 참조 형태로 관계를 바꾸는 것입니다. 만약 예로 TeamJpaEntity, MemberJpaEntity 클래스가 양방향 매핑으로 순환 참조가 있다고 가정합시다. TeamJpaEntity - @OneToMany MemberJpaEntity, MemberJpaEntity - @ManyToOne.. 2024. 11. 9.