묻고 답해요
158만명의 커뮤니티!! 함께 토론해봐요.
인프런 TOP Writers
-
미해결스프링 DB 2편 - 데이터 접근 활용 기술
REQUIRES_NEW를 호출한 트랜잭션의 롤백
학습하는 분들께 도움이 되고, 더 좋은 답변을 드릴 수 있도록 질문전에 다음을 꼭 확인해주세요.1. 강의 내용과 관련된 질문을 남겨주세요.2. 인프런의 질문 게시판과 자주 하는 질문(링크)을 먼저 확인해주세요.(자주 하는 질문 링크: https://bit.ly/3fX6ygx)3. 질문 잘하기 메뉴얼(링크)을 먼저 읽어주세요.(질문 잘하기 메뉴얼 링크: https://bit.ly/2UfeqCG)질문 시에는 위 내용은 삭제하고 다음 내용을 남겨주세요.=========================================[질문 템플릿]1. 강의 내용과 관련된 질문인가요? (예/아니오)2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예/아니오)3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예/아니오)[질문 내용]여기에 질문 내용을 남겨주세요. 안녕하세요 김영한님 !REQUIRES_NEW는 완전히 물리적으로 트랜잭션이 분리되어REQUIRED(A 메서드)에서 REQUIRES_NEW(B 메서드)를호출 했을 때 B 메서드에 발생한 예외가 A 메서드에 전파되지 않는다고 이해했습니다.실제 확인을 위해 아래 코드를 구성해@Service @RequiredArgsConstructor public class MeetingService { private final MeetingRepository meetingRepository; private final MemberService memberService; @Transactional public void save() { meetingRepository.save(new Meeting("스터디 모임", LocalDate.now(), LocalTime.now(), "AB3AS2EG")); memberService.save(); } @Transactional(readOnly = true) public List<Meeting> findAll() { return meetingRepository.findAll(); } } @Service @RequiredArgsConstructor public class MemberService { private final MemberRepository memberRepository; @Transactional(propagation = Propagation.REQUIRES_NEW) public void save() { memberRepository.save(new Member("김철수")); throw new IllegalArgumentException(); } @Transactional(readOnly = true) public List<Member> findAll() { return memberRepository.findAll(); } }아래 테스트 코드로 테스트를 진행했습니다.@Test void test() { assertThatThrownBy(() -> meetingService.save()) .isInstanceOf(IllegalArgumentException.class); // 롤백 여부 확인 List<Meeting> meetings = meetingService.findAll(); List<Member> members = memberService2.findAll(); assertThat(meetings).isEmpty(); assertThat(members).isEmpty(); }결과를 로그로 분석해보니 MemberService의 트랜잭션은 독립적으로 롤백 발생한 예외가 MeetingService로 전파 전파된 예외로 인해 MeetingService의 트랜잭션도 롤백이런식으로 흐름이 진행됐습니다. 제가 추측하기로는 물리적으로 분리는 되어 있지만 하나의 스레드에서 생긴 커넥션이고 자바의 예외 전파 메커니즘에 따라A 메서드에서 호출한 B 메서드의 예외가 A 메서드에 전파된 것이 아닌가 생각을 했는데요REQUIRES_NEW 사용 시 예외가 전파 되지 않는다. 라고 이해를 했어서 제가 실험한 결과가 맞는지 간과한 부분이 있었던 것인지 궁금합니다 !
-
미해결테스트 with Jest: 제로초에게 제대로 배우기
모듈 모킹 시 메소드 동작 문제
https://github.com/ayden94/jestTestsrc/module.spec.ts에서 jest.mock('./module')를 하면, 모듈이 이상하게 모킹되는 듯합니다. 메소드가 존재는 하지만, 호출할 경우 완전히 말이 안 되는 결과를 리턴해서 toBe가 항상 틀린 것으로 결과가 나옵니다. 모듈 모킹 시도 없이 모듈 그 자체를 가지고 테스트를 해보면 문제가 없는데, 꼭 모듈을 모킹하면 문제가 생깁니다. 고민해봤지만 원인을 모르겠습니다.확인 부탁드립니다.
-
미해결Airflow 마스터 클래스
(맥환경) dag 파일 인식 안됨
안녕하세요. 강사님 강의따라 docker-compose.yaml 수정 후 에어플로우 내렸다가 다시 올렸는데 dags_bash_operator가 local hostdp에서 보이지 않습니다. (다시 내렸다가 올려도 그대로네요..) 올리기 위해 어떻게 접근해볼 수 있을까요? 맥환경이고 캡처와 같이 수정까지 완료된 상황입니당.
-
미해결자바 ORM 표준 JPA 프로그래밍 - 기본편
연관관계가 없는 조인
연관관계가 없는 조인에 대해 설명하신 부분에 대해 문의 드립니다. 보통 연관관계가 없다고 한다면 외래키로 연결되지 않는 두개의 테이블 이라고 생각할텐데 강의에서는 두 테이블 간 연관관계는 존재하고 연관관계의 컬럼으로 조인하는것이 아닌 , 다른 컬럼으로 조인하는것을 연관관계가 없는 조인이라고 설명하시는것 같아 혼동이 옵니다. 연관관계가 없는 조인 의 경우 두 테이블 간에 외래키가 없는경우에도 연관관계 없는 조인이 가능한건지 아니면 외래키는 있지만 외래키 조인이 아닌 다른 컬럼으로 조인할수 있는것을 연관관계가 없는 조인이라고 하시는건지 알려 주시면 감사하겠습니다.
-
미해결[코드팩토리] [초급] Flutter 3.0 앱 개발 - 10개의 프로젝트로 오늘 초보 탈출!
프로젝트시작에서 에러
이거는 어떻게 처리하면 되나요실행은 됩니다
-
미해결스프링 핵심 원리 - 고급편
스프링의 빈 후처리기와 프록시 그리고 타겟에 대해 질문 있습니다.
학습하는 분들께 도움이 되고, 더 좋은 답변을 드릴 수 있도록 질문전에 다음을 꼭 확인해주세요.1. 강의 내용과 관련된 질문을 남겨주세요.2. 인프런의 질문 게시판과 자주 하는 질문(링크)을 먼저 확인해주세요.(자주 하는 질문 링크: https://bit.ly/3fX6ygx)3. 질문 잘하기 메뉴얼(링크)을 먼저 읽어주세요.(질문 잘하기 메뉴얼 링크: https://bit.ly/2UfeqCG)질문 시에는 위 내용은 삭제하고 다음 내용을 남겨주세요.=========================================[질문 템플릿]1. 강의 내용과 관련된 질문인가요? (예/아니오)2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예/아니오)3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예/아니오)[질문 내용]안녕하세요 항상 강의 잘 보고 있습니다. 강의에서 1.생성 : 스프링이 스프링 빈 대상이 되는 객체를 생성함 2.전달 : 생성된 객체를 빈 저장소에 등록하기 직전에 빈 후처리기에 전달함 ~ 그 후에프록시 적용대상인 클래스가 있으면3.프록시 생성 : 프록시 적용 대상이고, 프록시를 생성하고 반환해서 프록시를 스프링 빈으로 등록한다. 라고 말씀하셨습니다. 그 후에, 생성된 프록시와 어드바이저의 동작 과정을 설명하실 때 , client -> ( proxy <-> advisors ) -> target 이런 동작 과정이라고말씀하셨는데 이 부분에서 이해가 안되는 부분이 있습니다. 1.프록시 객체를 생성했는데 target을 호출하는 이유가 무엇인가요?예를 들어,프록시 객체는 target을 기반으로 만들어진 클래스라고 이해를 했습니다.그러면 프록시 객체는 target의 구현체로서 target의 메소드도 가지고 있고, advisor 메소드도 가지고 있는 것 아닌가요?그래서 그냥 타겟을 호출할 필요없이, 프록시 객체에서 모든 요청을 처리하면 되는것 아닌가요?? 왜 프록시 객체는 advisor을 호출하고, 다시 타겟을 통해서 메서드를 또 실행하는건가요? 즉, 전 프록시 객체를 만든다는 것을 아래와 같은 예시로 이해를 했습니다. 그래서 굳이 target을 다시 호출하지 않고, 프록시 객체가 모든 요청을 처리하는게 맞는거 같은데 왜 target을 다시 호출하는건가요?? // AClasspublic class AClass { public void say() { System.out.println("Hello from AClass!"); }}// LoggingAspectㅇ@Aspect@Componentpublic class LoggingAspect { @Before("execution(* com.example.AClass.say(..))") public void logBefore() { System.out.println("Before calling say method"); }} //Proxypublic class AClassProxy extends AClass { @Override public void say() { logBefore(); // 로그 출력 super.say(); // 실제 AClass의 say 메서드 호출 } public void logBefore() { System.out.println("Before calling say method"); }}감사합니다.
-
해결됨Spring Boot를 활용하여 채팅 플랫폼 만들어보기
JwtProvider 를 Component 로 선언하신 이유가 궁금합니다.
안녕하세요 지식공유자님. 강의에서 JwtProvider 에 @Component 어노테이션을 선언하셔서 스프링이 관리하도록 의도하신 것 같습니다. 그런데, 함수에 static 을 모두 붙이시고, 사용하는 쪽에서는 bean 으로 등록 하지 않고 static util 처럼 사용하시는 것을 확인했습니다.질문은 두가지 입니다.@Component 를 선언하셨음에도 static 메서드를 authService 에서 사용하신 이유가 있으신지.빈으로 만들고서도 static 함수로 사용하는 것에 이점이 있는 것인지.답변 부탁드리겠습니다. 감사합니다.
-
미해결스프링 핵심 원리 - 고급편
빈 후처리기와 프록시 그리고 @Transactional 관련 질문 있습니다.
학습하는 분들께 도움이 되고, 더 좋은 답변을 드릴 수 있도록 질문전에 다음을 꼭 확인해주세요.1. 강의 내용과 관련된 질문을 남겨주세요.2. 인프런의 질문 게시판과 자주 하는 질문(링크)을 먼저 확인해주세요.(자주 하는 질문 링크: https://bit.ly/3fX6ygx)3. 질문 잘하기 메뉴얼(링크)을 먼저 읽어주세요.(질문 잘하기 메뉴얼 링크: https://bit.ly/2UfeqCG)질문 시에는 위 내용은 삭제하고 다음 내용을 남겨주세요.=========================================[질문 템플릿]1. 강의 내용과 관련된 질문인가요? (예/아니오)2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예/아니오)3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예/아니오)[질문 내용]안녕하세요, 강사님. 항상 강의 잘 보고 있습니다.해당 강의를 듣고 개인 학습을 하던 중에 @Transactional에 대해 궁금한 점이 생겼습니다. 특히, **"@Transactional은 접근 제어자가 public이 아닌 메서드에는 적용되지 않는다"**는 부분에 대해 잘 이해가 되지 않았습니다.저는 이전에 강사님 강의를 듣고, @Transactional을 메서드에 적용할 때 빈 후처리기와 프록시 방식에 대해 아래와 같이 이해했습니다.A 클래스의 A 메서드에 @Transactional을 적용스프링은 해당 메서드에 트랜잭션을 적용할 수 있도록 AOP 기반으로 동적 프록시를 생성함.스프링 컨테이너가 @Transactional이 붙은 메서드를 가진 클래스는 AOP가 적용된 클래스임스프링은 @Transactional이 적용된 메서드를 감지하여, 트랜잭션을 적용하기 위해 AOP 기능을 사용함.스프링 컨테이너에 A 클래스를 bean으로 등록할 때, 빈 후처리기에서 A 클래스의 프록시 객체를 스프링 빈으로 등록스프링에서는 빈 후처리기에서 트랜잭션을 적용하는 프록시 객체를 생성함. 실제 A 객체가 아닌 프록시 객체가 빈으로 등록되며, 이 프록시 객체는 실제 A 클래스의 메서드들을 호출할 때 트랜잭션을 관리하는 추가 로직을 삽입함.그런데 이렇게 생성되고 사용될 때, **"@Transactional은 접근 제어자가 public이 아닌 메서드에는 적용되지 않는 이유"**가 잘 이해되지 않습니다.예를 들어, 아래와 같은 코드에서:public class MyService { @Transactional public void performAction() { // 트랜잭션이 필요한 메서드 } } 프록시 객체는 다음과 같이 생성될 것이라고 생각했습니다:public class MyServiceProxy extends MyService { @Override @Transactional public void performAction() { // 트랜잭션 관련 로직 추가 (시작, 커밋, 롤백 등) // 원래의 MyService.performAction() 호출 super.performAction(); } } 그런데, "왜 @Transactional이 붙은 메서드는 public이 아닌 접근 제어자에는 적용되지 않나요?" 이 부분에 대한 설명이 부족하여 궁금합니다.왜냐하면, 어차피 기존 클래스를 바탕으로 만들어지는게 프록시 객체라면 @Transactional을 적용할때, 접근 제어자가 왜 중요한지 잘 이해가 안됩니다설명 부탁드립니다
-
미해결자바와 스프링 부트로 생애 최초 서버 만들기, 누구나 쉽게 개발부터 배포까지! [서버 개발 올인원 패키지]
안녕하세요 코드 관련 질문이 있습니다!
최태현 강사님의 강의를 들으며 잘 배우고 있습니다!강사님의 코드를 보고 이해하며 따라가다가도 코드를 잘못 작성해 오류가 뜨는 경우가 많아 강사님 코드 전체를 보고 클론코딩을 하고 싶어 글 올립니다! 혹시 전체 코드를 받을 수 있을까요?
-
해결됨[리뉴얼] 맛집 지도앱 만들기 (React Native & NestJS)
WINDOWS로 강의 수강
제가 MacOS가 아니라 Windows인데 강의를 원활하게 수강할 수 있나요?
-
해결됨외워서 끝내는 네트워크 핵심이론 - 응용
웹서버의 정확한 인식이 궁금합니다.
안녕하세요. 질문이 있습니다. 웹서버가 3.3.3.3에 관해 인식을 어떻게 하는지가 조금 헷갈립니다. 11:31에서 웹서버는 3.3.3.3:23000 이랑 연결되었다고 인식한다고 하셨고(포트번호 언급), 14:03에서는 웹서버에 3.3.3.3:23000, 3.3.3.3:23001을 요청하면 웹서버는 3.3.3.3 과 2번 접속했다고 인식한다고 하셨습니다.(포트번호 미언급) 질문입니다.웹서버는 포트를 인식하는 것 같은데,포트가 달라도 IP가 같다면 하나의 클라이언트가 2번 요청했다고 인식하는 건가요? 정확히 웹서버는 어떻게 인식하는건가요?" 3.3.3.3:23000과 3.3.3.3:23001 요청이 각각 한번씩 들어왔구나. 3.3.3.3의 IP를 가진 클라이언트 하나가 2개의 포트를 사용해서 요청을 했구나. → 같은 클라이언트가 2번 요청했구나 " 이렇게 인식한다는 말씀이신지요? 그러니까 웹서버 입장에서는 포트는 크게 신경을 안쓰는건지요?
-
해결됨[리뉴얼] 맛집 지도앱 만들기 (React Native & NestJS)
Matzip.fig 관련 문의
방금 강의 결제해서 시작하고 있는데, 처음부터 안 되네요.사진 첨부합니다!
-
미해결FreeRTOS 프로그래밍
TaskDelay와 printf 순서
1번 실습 파일에 printf 를 찍을 때 vTaskDelay를 하고나서 왜 Printf를 찍나여? 뭔가 의미상으론 태스크가 할일(Printf 찍는 것)을 하고 Delay에 빠지는게 맞는 것 같은데 왜 TaskDelay 이후에 printf를 찍는 지 궁금합니다. vTaskDelay (pdMS_TO_TICKS (1000)); // 스스로 휴면상태에 들어감 Blocked로 다시 1000ms 후running printf("b"); fflush(stdout); // 문자 'a' 출력
-
미해결10주완성 C++ 코딩테스트 | 알고리즘 코딩테스트
1-G 질문이 있습니다.
제가 처음 작성했던 코드는 다음과 같습니다. 1번 코드 (처음 작성한 코드) http://boj.kr/a88f71f09ca849eab6009b62163b7a562번 코드 (substr 활용한 코드) http://boj.kr/589098635bfd4acb8726f8a5cbc18157선생님 풀이를 보고 substr을 활용해서 작성해 봤을 때, 사이즈 체크 조건문에 대해 질문이 있어서 글 남깁니다. 1번 코드에서는 사이즈 체크하는 조건문과 패턴을 확인하는 조건문을 같은 시점에 비교해도 정답이 나왔습니다. 하지만 2번 코드에서는 사이즈 체크를 먼저하고 -> 그 이후에 사이즈 조건을 만족할 때 패턴을 비교하는 코드를 넣어야만 올바른 답이 도출됩니다.이게 왜 차이가 나는것인지 설명해주시면 감사하겠습니다!
-
미해결한 입 크기로 잘라 먹는 리액트(React.js) : 기초부터 실전까지
checkbox onChange 적용 시 오류
checkbox를 클릭할 때 아래와 같은 오류가 발생합니다.코드는 동일하게 작성한 것 같은데 원인이 무었일까요?
-
해결됨홍정모의 따라하며 배우는 C언어
11.3 (8 : 35) 질문드립니다. (널 문자, 빈칸)
질문 수정 중 실수로 글을 지워 재질문 드립니다. #include <stdio.h> int main() { const char* mythings[5] = { "Dancing in the rain", "Couting apples", "Watching movies with friends", "Writing sad letters", "Studying the C language" }; char yourthings[5][40] = { "Studying the C++ language", "Eating", "Watching Netflix", "Walking around till dark", "Deleting spam emails" }; const char* temp1 = "Dancing in the rain"; const char* temp2 = "Studying the C language"; printf("%s %u %u\n", mythings[0], (unsigned)mythings[0], (unsigned)temp1); printf("%s %u %u\n", yourthings[0], (unsigned)yourthings[0], (unsigned)temp2); printf("\n"); printf("%-30s %-30s\n", "My Things:", "Your Things:"); for (int i = 0; i < 5; i++) printf("%-30s %-30s\n", mythings[i], yourthings[i]); printf("\nsizeof mythings:%zd, sizeof your yourthings:%zd\n", sizeof(mythings), sizeof(yourthings)); for (int i = 0; i < 100; i++) printf("%c", mythings[0][i]); printf("\n"); printf("\n"); for (int i = 0; i < 200; i++) printf("%d", (int)yourthings[0][i]); printf("\n"); for (int i = 0; i < 200; i++) printf("%c", yourthings[0][i]); printf("\n"); printf("\n"); return 0; } 첨부 이미지는 해당 코드의 마지막 for문 2개의 출력 결과입니다.강의와 다르게 마지막 for문이 띄어쓰기 없이 출력되고 있는데, 널 문자와 공백 문자가 다른 아스키 값을 가지고 있다는 것을 인지하고 있긴 합니다만, 교수님의 출력과 저의 출력이 달라서 질문드렸습니다.실행 환경에 따라서 출력이 다를 수 있는 건지, 아님 제가 놓치고 있는 부분이 따로 있는 건지 궁금합니다.
-
미해결[코드팩토리] [초급] Flutter 3.0 앱 개발 - 10개의 프로젝트로 오늘 초보 탈출!
설치문의
o/s:윈도우10 pro 22h2 ASUS 노트북 사용자입니다5년 되었습니다cpu:Intel(R) Core(TM) i7-7500U CPU @ 2.70GHz 2.90 GHzram:16.0GB(15.9GB 사용 가능)종류:64비트 운영 체제, x64 기반 프로세서230GB_hdd c: 플러터,안드로이드 스튜디오,git,node 설치230GB_hdd d:프로젝트 생성저는 이렇게 쓰고 있는데 문제 소지가 있으면 변경 하려고 합니다노트북이 오래 되어서 C:드라이브가 80% 되니 버벅거려서요"꼭 프로잭트생성 드라이브를 C:드라이브로 해야합니까'프로젝트생성을 D:할경우 문제가 많이 생기나요?
-
미해결Practical Testing: 실용적인 테스트 가이드
재고 엔티티 설계
안녕하세요 이번에 강의를 들으면서 동시성 문제를 실제 프로젝트에서 해결해보자는 취지에 엔티티 설계에 대한 고민이 생겨 질문 드립니다! public class Item { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long no; // 상품 : 품목 = 1 : N @ManyToOne(fetch = FetchType.LAZY) @JoinColumn(name = "prod_no", nullable = false) private Product product; @Column(name = "thumbnail_img_url") private String thumbNailImgUrl; // 대표 이미지 경로 // 품목옵션에 대한 필드 리스트 @OneToMany(mappedBy = "item", cascade = CascadeType.ALL, orphanRemoval = true) private List<ItemOption> itemOptions = new ArrayList<>(); private String code; // 품목코드 -> 상품코드 + 1 을 붙인 것 private String name; // 품목명 -> 옵션 그룹 + 옵션 값 @Column(name = "add_price", precision = 10, scale = 2) private Integer addPrice; // 추가금액 private Integer totalPrice; // 정상가격(원가) + 추가금액 private Integer qty; // 재고량 @Column(name = "saf_qty") private Integer safQty; // 안전재고량 @Enumerated(EnumType.STRING) private ProductSellingStatus sellingStatus; // 판매 상태 @Column(name = "max_qty") private Integer maxQty; // 최대 구매 수량 @Column(name = "min_qty") private Integer minQty; // 최소 구매 수량 } 현재 품목 엔티티라는 엔티티가 있습니다. 이 엔티티는 상품 + 옵션이 결합된 형태입니다. 그래서 재고 필드를 해당 엔티티에 정의 해주었습니다.근데 여기서 들었던 의문점이 " 재고 엔티티를 따로 정의를 안해줘도 괜찮을까? " 라는 의문점이 들기 시작했습니다. 그래서 일단 확장성을 고려하지 않고 구현을 하게 된다면 이대로 품목 엔티티가 재고 필드를 가지고 있는 것도 괜찮을거 같다는 생각이 들었습니다. 하지만 확장성을 고려하게 된다면 재고 엔티티를 정의해 품목 엔티티와 일대일 관계를 갖도록 하는 것이 좋다고 생각하였습니다." 확장성을 제외한 동시성 제어만을 고려했을 때 해당 설계도 괜찮을까? " 와 " 더 나은 설계는 무엇이 있을까? "에 대하여 조언을 듣고 싶습니다!!!
-
미해결실전! 스프링 부트와 JPA 활용2 - API 개발과 성능 최적화
@PathVariable과 @RequestBody의 차이
학습하는 분들께 도움이 되고, 더 좋은 답변을 드릴 수 있도록 질문전에 다음을 꼭 확인해주세요.1. 강의 내용과 관련된 질문을 남겨주세요.2. 인프런의 질문 게시판과 자주 하는 질문(링크)을 먼저 확인해주세요.(자주 하는 질문 링크: https://bit.ly/3fX6ygx)3. 질문 잘하기 메뉴얼(링크)을 먼저 읽어주세요.(질문 잘하기 메뉴얼 링크: https://bit.ly/2UfeqCG)질문 시에는 위 내용은 삭제하고 다음 내용을 남겨주세요.=========================================[질문 템플릿]1. 강의 내용과 관련된 질문인가요? (예/아니오)2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예/아니오)3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예/아니오)[질문 내용]여기에 질문 내용을 남겨주세요. @PatchMapping("/api/v2/members/{id}") public UpdateMemberResponse updateMember(@PathVariable("id") Long id, @RequestBody @Valid UpdateMemberRequest updateMemberRequest) { 수정 api는 위와 같은 주소를 이용합니다.근데 사실 UpdateMemberRequest에 id라는 필드를 넣고 주소를 /api/v2/members 로 둬도 상관 없지 않나요?id를 PathVariable로 뺀 이유가 궁금합니다
-
해결됨실전! 스프링 부트와 JPA 활용2 - API 개발과 성능 최적화
탬플릿 엔진을 사용할때는 DTO를 사용하지 않는 이유
학습하는 분들께 도움이 되고, 더 좋은 답변을 드릴 수 있도록 질문전에 다음을 꼭 확인해주세요.1. 강의 내용과 관련된 질문을 남겨주세요.2. 인프런의 질문 게시판과 자주 하는 질문(링크)을 먼저 확인해주세요.(자주 하는 질문 링크: https://bit.ly/3fX6ygx)3. 질문 잘하기 메뉴얼(링크)을 먼저 읽어주세요.(질문 잘하기 메뉴얼 링크: https://bit.ly/2UfeqCG)질문 시에는 위 내용은 삭제하고 다음 내용을 남겨주세요.=========================================[질문 템플릿]1. 강의 내용과 관련된 질문인가요? (예/아니오)2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예/아니오)3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예/아니오)[질문 내용]여기에 질문 내용을 남겨주세요. 엔티티를 api로 넘겨주면 엔티티가 수정됐을때 api가 오염될 수 있는 문제가 있어서 응답에 DTO를 보내준다고 이해했습니다.근데 이 문제는 탬플릿 엔진을 사용해 화면을 출력할때도 문제가 되지 않나요?1편에서 타임리프에 값을 넣을때는 DTO를 이용하지 않은 이유가 궁금합니다.혹시 컴파일 단계에서 오류가 나기 때문인가요?