일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | |||
5 | 6 | 7 | 8 | 9 | 10 | 11 |
12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 | 20 | 21 | 22 | 23 | 24 | 25 |
26 | 27 | 28 | 29 | 30 | 31 |
- visualvm
- 쇼트유알엘
- WEB SOCKET
- 카프카
- 남궁성과 끝까지 간다
- 프로그래머스
- MYSQL
- 패스트캠퍼스
- 시큐리티
- JWT
- AWS
- 스웨거
- JavaScript
- Kafka
- EC2
- Spring Security
- 웹개발
- java
- CentOS
- Spring
- 개인프로젝트
- 스프링의 정석
- 데이터베이스
- emqx
- @jsonproperty
- docker
- 스파르타코딩클럽
- 항해99
- DB
- 생성자 주입
- Today
- Total
목록회고록 (121)
Nellie's Blog
배운점 김영한 JPA강의를 2-10 강 수강했다. 배우기 앞서서 MyBatis를 제대로 모르는 것 같아서 블로그를 참고해서 공부했다. (노트에 정리했다) root-context라는 개념이 나와서 스프링MVC 동작원리도 공부했다. (마찬가지로 노트정리) JPA책 3장인 영속성 관리를 정리했다. 조각나있던 개념이 조금 잡히는 것 같다. https://yeees.tistory.com/131 JPA 3장 영속성 관리 사전지식 - MyBatis 기본 사용법 영속성 컨텍스트 엔티티를 영구 저장 하는 환경 영속성 컨텍스트는 엔티티 매니저를 통해 엔티티를 조회하거나 저장할때 엔티티를 보관하고 관리한다. 바로 데이 yeees.tistory.com 느낀점 제대로 아는게 많이 없어서 하나를 공부해도 오래걸리는 것 같다. 공..
배운점 @ResponseBody https://wildeveloperetrain.tistory.com/144 @RequestBody @ResponseBody 어노테이션 이해하고 사용하기 클라이언트와 서버의 통신(HTTP) @RequestBody, @ResponseBody Annotation을 이해하기에 앞서, 클라이언트와 서버 간 통신에 대해서 먼저 간단하게만 살펴보겠습니다. HTTP(HyperText Transfer Protocol) 통신이란, 브 wildeveloperetrain.tistory.com https://tecoble.techcourse.co.kr/post/2021-05-10-response-entity/ ResponseEntity - Spring Boot에서 Response를 만들자 웹 ..
배운점 미니프로젝트를 진행하기에 앞서 기초지식이 부족한 것 같아 항해99에서 받은 강의를 쭉 보려고 하는데, 깊이 알지 못했던 지식들이 보여 정리를 하는 시간을 가졌다. Enum의 정리도 하고, HTTP 에 대한 이해도 부족한 것 같아 정리를 해봤고, JPA를 배우기 전에 SQL문법도 숙달되지 않은 것 같아서 프로그래머스 레벨1 20문제도 다 풀었다. SQL문법을 공부하는 문제도 있는줄 몰랐는데, 아주 유용하게 숙달할 수 있었다. 나머지 레벨 문제도 곧 다 풀어야겠다. https://yeees.tistory.com/127 HTTP Request/Response 구조 HTTP Request HTTP Request Message는 공백(blank line)을 제외하고 3가지 부분으로 나누어진다. Start ..
공부한것 프로젝트 ERD 에 맞추어 entity를 작성해보았다. https://yeees.tistory.com/125 [개인프로젝트] 붕어빵사이트 ERD에 따른 entity설계 User package com.example.streetsnack.entity; import lombok.Getter; import lombok.NoArgsConstructor; import javax.persistence.*; import java.util.ArrayList; import java.util.List; @Getter @NoArgsConstructor @Entity(name = "users") public class User { @Id @G yeees.tistory.com JPA 연관관계 잡는 것이 가장 어려웠는데,..
공부한 것 개인프로젝트 ERD설계를 했다. 시작하려니 너무 막막했다. 테이블만 작성하고 계속 멍때렸다. 부트캠프에서는 정말 간단한 프로젝트여서 지금 하는 프로젝트의 여러 데이터베이스를 보니 어디서부터 손을 대야할 지 막막했다. 일단 연관관계 부분도 헷갈려서 자바 ORM 표준 JPA 프로그래밍 책으로 다시 공부했다. 블로그도 찾아보면서 ERD작성법을 공부했다. 부트캠프에서는 얼레벌레 느낌따라(?) ERD를 작성해서 관계형 데이터베이스설계에 4단계가 있는 줄도 몰랐는데, 자세히 찾아보니 다 단계가 있었다. 천천히 따라하니까 막막했던 ERD설계도 차근히 할 수 있었다. https://yeees.tistory.com/123 [개인프로젝트] 붕어빵사이트 ERD설계 관계형 데이터베이스를 설계할 시, 아래의 4단계를..
공부한 것 https://yeees.tistory.com/120 [Docker] 도커의 개념과 구조 및 명령어 1. Docker란 Docker는 가상 머신처럼 독립된 실행환경을 만들어주는 것으로, 운영체제를 설치한 것과 유사한 효과를 낼 수 있지만, 실제 운영체제를 설치하지 않기 때문에 설치 용량이 적고 실행 속 yeees.tistory.com https://yeees.tistory.com/121 개인프로젝트 관심사별 채팅사이트 와이어프레임작성 오픈 API는 3개 사용할 예정이다. 1. 위치 & 날씨 API 2. 영양정보 API 3. 구글 지도 API yeees.tistory.com 느낀점 본격적으로 프로젝트를 진행하려고 한다. 프로젝트에 오픈 API가 있으면 더 재밌는 웹사이트가 될거 같아서 찾아봤는데..
[목차] 1. Spring Security 란? 2. Spring Security 주요 컴포넌트 확인하기 3. Spring Security의 Default Form Login 방식 사용해보기 4. UserDetails, UserDetailsService Custom 해보기 5. 비밀번호 암호화 이해하고 적용하기 6. CustomSecurityFilter 적용해보기 7. @AuthenticationPrincipal 8. @Secured 9. 401, 403 Error ExceptionHandling 해보기 10. Security에서 JWT를 사용한 인증/인가 흐름 짚고 넘어가기 목차 중 1,2,10번만 정리했다. 1. Spring Security 란? 'Spring Security' 프레임워크는 스프링 서..
정말 솔직하게 항해99 하차후기를 써보려한다. 0주차 프리온보딩, 1주차 플라스크 미니프로젝트, 2주차 알고리즘, 3주차 스프링기초, 4주차 스프링숙련, 5주차 스프링심화까지 수료를 했고, 6주차 미니프로젝트 진행중에 하차를 했다. 약 한달반의 기간이 흘렀고, 항해99로 인해 많은 것을 배운건 사실이다. 그러나 나와는 맞지 않는 부분이 많았고 과감히 하차를 결정했다. 1. 충분하지 않은 자료와 과한 과제요구사항 인강을 주고, 과제를 해내라는 식으로 진행이 된다. 물론 인강이 아주 양이 적기 때문에 알아서 질 좋은 강의를 찾아서 들어야한다. 그런데, 인강을 주고 나서 2~3일 뒤에 코드리뷰를 한다. 미리 관련 지식이 없는 학생입장에서는 굉장히 난감하다. (스프링강의를 잠깐 보긴했지만 스프링부트는 조금 달랐..
AWS의 기본서비스 S3, EC2, RDS AWS는 Amazon Web Service, 즉 아마존에서 제공하는 클라우드 서비스로 다양한 서비스를 제공한다. AWS는 쉽고 빠른 확정성을 제공하고 저렴한 비용으로 사용한 용량 만큼만 비용을 지불하며 빠른 속도 등 여러가지 장점을 지니고 있다. AWS 서비스 중 3가지 S3, EC2, RDS에 대해서 알아보고자 한다. 1. S3 S3(Simple Storage Service)는 데이터를 저장하거나 추출하게 해 주는 온라인 스토리지 웹 서비스이다. 즉 파일 서버의 역할을 하는 서비스이다. 하나의 저장 공간을 구성하고 그 공간에 데이터를 자유롭게 업로드, 다운로드 할 수 있다. HTTP 프로토콜로 파일에 접근할 수 있다. 일반적인 시스템과는 다르게 파일(또는 데이..
학습 과제의 목표 Git 원격 repo를 사용할 수 있고, branch 전략을 세워 협업 환경을 구성하여 개발할 수 있어요. 복잡한 비즈니스 요구사항을 보고 연관관계를 정하고 구현해 낼 수 있어요. Spring Security를 사용하여 인증/인가를 구현해 낼 수 있어요. 추가된 요구사항 숙련주차 개인과제 LV2 프로젝트에 Spring Security 적용하기 게시글 좋아요 API 사용자는 선택한 게시글에 ‘좋아요’를 할 수 있습니다. 사용자가 이미 ‘좋아요’한 게시글에 다시 ‘좋아요’ 요청을 하면 ‘좋아요’를 했던 기록이 취소됩니다. 요청이 성공하면 Client 로 성공했다는 메시지, 상태코드 반환하기 댓글 좋아요 API 사용자는 선택한 댓글에 ‘좋아요’를 할 수 있습니다. 사용자가 이미 ‘좋아요’한 ..
배운점 Refresh Token 이란? 목적 결론부터 말하자면 Refresh Token의 목적은 Access Token의 유효 기간을 짧고, 자주 재발급 하도록 만들어 보안을 강화하면서도 사용자에게 잦은 로그아웃 경험을 주지 않도록 하는 것이다. Access Token은 리소스에 접근하기 위해서 사용되는 토큰이라면, Refresh Token은 기존에 클라이언트가 가지고 있던 Access Token이 만료되었을 때 Access Token을 새로 발급받기 위해 사용한다. 유효 기간 Refresh Token은 Access Token 대비 긴 유효 기간을 갖는다. Refresh Token을 사용하는 상황에서는 일반적으로 Access Token의 유효기간은 30분 이내, Refresh Token의 유효기간은 2주..
배운점 Optional Java8에서는 Optional 클래스를 사용해 NPE를 방지할 수 있도록 도와준다. Optional는 null이 올 수 있는 값을 감싸는 Wrapper 클래스로, 참조하더라도 NPE가 발생하지 않도록 도와준다. Optional 클래스는 아래와 같은 value에 값을 저장하기 때문에 값이 null이더라도 바로 NPE가 발생하지 않으며, 클래스이기 때문에 각종 메소드를 제공해준다. Optional 클래스는 내부에서 static 변수로 EMPTY 객체를 미리 생성해서 가지고 있다. 이러한 이유로 빈 객체를 여러 번 생성해줘야 하는 경우에도 1개의 EMPTY 객체를 공유함으로써 메모리를 절약하고 있다. Optional은 null 또는 값을 감싸서 NPE(NullPointerExcepti..
트러블슈팅 1. 시큐리티 프로젝트 실행 시 , o.s.b.d.LoggingFailureAnalysisReporter 에러 발생 다른 프로젝트가 실행 중이었기 때문에, 8080포트를 이미 사용하고 있어서 에러가 발생했다. 다른 프로젝트를 실행 중지시켜서 해결하였다. 2. Cannot find symbol 에러 클래스명 오타를 수정하니 해결 되었다. CustomAccessDeniedHandler -> CustomAccessDeniedHandle 3. rawPassword cannot be null 아래와 같은 에러로그를 나타내며 회원가입 postman에서 500에러가 났다. Dto를 받아오는 파라미터 앞에 @RequestBody 를 추가해주었다. 느낀점 시큐리티를 하루종일 공부했다. 알듯말듯 어렵지만 그래도..
배운점 리플렉션 리플렉션은 구체적인 클래스 타입을 알지 못해도, 그 클래스의 메소드, 타입, 변수들에 접근할 수 있도록 해주는 자바 API 자바는 정적인 언어라 부족한 부분이 많은데 이 동적인 문제를 해결하기 위해서 리플렉션을 사용한다. 정적 언어: 컴파일 시점에 타입을 결정 ex) Java, C, C++ 등.. 동적 언어: 런타임 시점에 타입을 결정 ex) Javascript, Python, Ruby 등.. 리플렉션은 애플리케이션 개발에서보다는 프레임워크, 라이브러리에서 많이 사용된다. 프레임워크, 라이브러리는 사용하는 사람이 어떤 클래스를 만들지 모른다. 이럴 때 동적으로 해결해주기 위해서 리플렉션을 사용한다. 대표적인 사용 예로는 스프링의 DI(dpendency injection), Proxy, M..
트러블슈팅 1. 코드 실행시 다음과 같이 쿼리 작성에 실패 했다는 에러로그가 뜨며 실행이 안됨 쿼리문에서 'Or' 를 빼주니까 해결되었다. 구글링해보니 JPA에서는 쿼리 메소드를 카멜케이스로 잘 작성해야 돌아가는 것 같다. 쿼리 작성에 유의하자! 2. 숙련주차 과제 중 엔티티간의 pk가 매핑이 안되는 문제(Post/ Comment) 1) Post에 null이 나오는 문제 User엔티티에 위와 같이 설정했는데, null이 나왔다. 이유는 PostService에서 user.add(post)를 추가를 안해줬기 때문이다! 아래와 같이 Post에서 세팅해주고, PostService에서 post.setUser(user); 해도 된다! 이걸 더 추천! (User는 한번 생성하고, Post만 계속 만들기 때문에) 2)..
배운점 아이디 비밀번호 유효성검사(@NotBlank, @Pattern) 느낀점 발표하고 긴장이 풀리고 너무 졸려서 계속 잤다.. 집에서 공부하니 정신을 못차리는 거 같다. 긴장하고 정신 차려야겠다.
트러블슈팅 1. 회원가입 api에서 post가 전송이 안되며 에러 (DataIntegrityViolationException) 서버 에러로그 -> DataIntegrityViolationException 컨트롤러에서 signupRequestDto에서 정보를 제대로 못받아오는 현상이 있었다. Dto값도 맞게 넣고, 중복되지 않게 잘 넣었는데 어떤게 문제일까 2시간동안 헤맸다. 이유는 @Controller 이 어노테이션 때문 ............................... @Controller어노테이션은 json타입으로 들어온다는 명시가 없기 때문에 Dto에서 정보를 못 받아 왔던 것이었다! @RestController로 바꿔주니 바로 해결 되었다. @RestController는 단순히 객체만을 반..
UserController & SignupRequestDto / LoginRequestDto UserService UserRepository Entity - User / UserRoleEnum JwtUtil UserController package com.sparta.myselectshop.controller; import com.sparta.myselectshop.dto.LoginRequestDto; import com.sparta.myselectshop.dto.SignupRequestDto; import com.sparta.myselectshop.service.UserService; import jakarta.servlet.http.HttpServletResponse; import lombok.Req..
배운점 효율적인 모델링 작업하기 (정규화) 도서 Entity에 관해서 말하자면, 도서관의 같은 책(책 이름이 똑같은)이 있다는 가정하에 모델링을 했음에도 불구하고, 이것을 효율적으로 못한 모델링을 한 표본이 되고 말았다. 왜냐하면 도서번호로 같은 책이 있더라도 번호를 달리해 구분은 가능할지 몰라도, 똑같은 자료를 중복하게되는 구조여서 결과적으로 데이터공간을 낭비하는 결과를 초래하기 때문이다. 다시 말하면 도서관의 실제도서를 나타내는 Entity와 실제도서의 속성을 정의하는 Entity를 구분해야된다는 말이다. 왜냐하면, 도서번호만 다른 똑같은 책인 속성 정보가 완전히 같기 때문에 아래 사진에서 볼수 있듯이 같은 도서의 속성들의 데이터가 중복으로 저장됨을 표로 볼 수 있다. 따라서 이 속성정보를 중복해..
[목차] Ⅰ.영속성 컨텍스트 00. 들어가기 전에 01. 영속성 컨텍스트란? 02. 영속성 컨텍스트는 어떻게, 왜 이렇게 설계되어있을까요? Ⅱ. 엔티티 매핑 심화 01. 기본 엔티티 매핑 관련 02. 연관관계 관련 심화 03. 양방향 연관관계의 주의점 04. 프록시 Ⅰ.영속성 컨텍스트 00. 들어가기 전에 우리가 Spring Data JPA로 해오던 방식 // Entity를 생성! Member minsook = new Member(); member.setId("abcd1234"); member.setUsername("민숙"); // 아래의 내용은 똑같은 과정! memberRepository.save(minsook); memberRepository.find(); 우리가 Spring Data JPA를 사용하..
학습 과제의 목표 회원가입, 로그인을 구현할 수 있어요. 인증/인가를 이해하고 JWT를 활용하여 게시글 및 댓글을 처리할 수 있어요. JPA 연관관계를 이해하고 회원, 게시글 및 댓글을 구현할 수 있어요. 서비스 완성 요구사항 회원 가입 API username, password를 Client에서 전달받기 username은 최소 4자 이상, 10자 이하이며 알파벳 소문자(a~z), 숫자(0~9)로 구성되어야 한다. password는 최소 8자 이상, 15자 이하이며 알파벳 대소문자(a~z, A~Z), 숫자(0~9), 특수문자로 구성되어야 한다. DB에 중복된 username이 없다면 회원을 저장하고 Client 로 성공했다는 메시지, 상태코드 반환하기 회원 권한 부여하기 (ADMIN, USER) - ADM..
배운점 DI(Dependency Injection) DI(Dependency Injection)란 스프링이 다른 프레임워크와 차별화되어 제공하는 의존 관계 주입 기능으로, 객체를 직접 생성하는 게 아니라 외부에서 생성한 후 주입 시켜주는 방식이다. DI(의존성 주입)를 통해서 모듈 간의 결합도가 낮아지고 유연성이 높아진다. 첫번째 방법은 A객체가 B와 C객체를 New 생성자를 통해서 직접 생성하는 방법이고, 두번째 방법은 외부에서 생성 된 객체를 setter()를 통해 사용하는 방법이다. 이러한 두번째 방식이 의존성 주입의 예시인데, A 객체에서 B, C객체를 사용(의존)할 때 A 객체에서 직접 생성 하는 것이 아니라 외부(IOC컨테이너)에서 생성된 B, C객체를 조립(주입)시켜 setter 혹은 생성자..
배운점 엔티티 연관관계 매핑 다중성 다대일(@ManyToOne) 일대다(@OneToMany) 일대일(@OneToOne) 다대다(@ManyToMany) 단방향, 양방향 단방향: 객체 관계에서 한쪽만 참조 양방향: 객체 관계에서 양쪽이 서로 참조 연관관계의 주인 두 객체 연관관계 중 외래 키를 관리하는 쪽을 주인이라 함 외래 키를 가진 테이블과 매핑한 엔티티를 보통 연관관계의 주인으로 선택 주인이 아닌 방향은 외래 키 변경 불가, 읽기만 가능 주인이 아닌 쪽은 mappedBy 속성을 사용하여 주인 필드 이름을 값으로 입력 느낀점 엔티티 연관관계를 공부했다. 모호했는데 조금씩 개념이 잡혀가는 것 같다. https://mjmjmj98.tistory.com/152
학습 과제의 목표 Java를 활용하여 필요한 클래스를 구상할 수 있어요. Lombok과 JPA를 이용하여 원하는 데이터베이스를 만들고 활용할 수 있어요. Spring Boot를 기반으로 CRUD(Create, Read, Update, Delete) 기능이 포함된 REST API를 만들 수 있어요. 과제 주의사항 Entity를 그대로 반환하지 말고, DTO에 담아서 반환해주세요! 프론트엔드와 백엔드가 느슨하게 결합하는 환경이 ”최근에는” 더 일반적이라고 말씀드렸죠? 앞으로 남은 강의 예제와 실습에서는 html/css/js 즉 뷰도 같이 반환 하겠지만, 과제에는 여러분들이 서버 로직에 더 집중하실 수 있도록 JSON을 반환하는 API형태로 진행하려고 합니다. 눈으로 직접 확인 할 수 있었던 view와는 다르..
트러블슈팅 1. 블로그에서 postman 으로 post요청시 시간이 null 값으로 나오는 문제 → @SpringBootApplication 이 있는 class 에 @EnableJpaAuditing 추가를 안해줘서 생긴 문제!!! 2. 커밋할 때 히스토리가 꼬여서 Couldn't add remote: remote origin already exists 에러 발생 → 인텔리제이 터미널창에서 git push -f origin master 명령어로 강제 푸쉬로 해결함 (경로를 하나로 합쳐줌) 리드미 파일을 추가한 후, 풀을 당겨줘야 히스토리 꼬이지 않는다. 항상 풀을 먼저 하고 작업을 하자!!!! 느낀점 입문주차 과제를 다시 써보며 복습했다. 숙련주차 과제를 하기 전에, 다시 정리를 안하면 머리속이 너무 꼬일..
배운점 영속성 컨텍스트 엔티티매니저에는 공유하면 안되는 특정 리소스나 정보가 있고, 여러 스레드가 하나의 엔티티 매니저를 이용 할 수 없도록 처리해야 한다. 그래서 엔티티 매니저 팩토리에서 필요 할 때 마다 여러개의 엔티티매니저를 생성하는 구조로 설계한다. 엔티티 매니저마다 개별적으로 부여되는, 어떠한 논리적 공간같은 개념이다. 자바의 엔티티 객체를 엔티티 매니저마다 가지고 있는 영속성 컨텍스트라는 공간에다 넣고 빼고 하면서 사용한다. “영속화 한다” 라는 말은, “엔티티 매니저가 자기의 영속성 컨텍스트에 넣어준다”와 같은 의미이다. 1차 캐시라는 것을 가지고 있다. 굳이 여러번 DB를 방문하지 않도록. “쓰기 지연 SQL 저장소”가 있다. 역시 굳이 여러번 DB를 방문하지 않도록. DirtyChecki..
배운점 어떤 상황에서 어떤 Request를 쓰나? @RequestParam : URI 경로에서 값을 추출 URI에 이어지는 '?' 뒤에 key1=value1&key2=value2& 형태(Query String)에서 값을 추출. @PathVariable : URI 경로에서 값을 추출 (대분류/중분류/소분류) 의 형태로 작성. @RequestBody : URI경로에서 데이터를 받을 수 없는 경우 필요로 하는 클래스 및 getter method가 선언되어있다면 자동으로 데이터를 받아와 객체 생성 Json(application/json) 형태의 HTTP Body를 Java Object로 변환 @ModelAttribute URI경로에서 데이터를 받을 수 없는 경우 외부 데이터가 bean에 등록된 객체로 자동 변환..
배운점 @Transactional 어노테이션 @Transactional은 클래스나 메서드에 붙여줄 경우, 해당 범위 내 메서드가 트랜잭션이 되도록 보장해준다. 선언적 트랜잭션이라고도 하는데, 직접 객체를 만들 필요 없이 선언만으로도 관리를 용이하게 해주기 때문. 특히나 SpringBoot에서는 선언적 트랜잭션에 필요한 여러 설정이 이미 되어있는 탓에, 더 쉽게 사용할 수 있다. 연산이 고립되어, 다른 연산과의 혼선으로 인해 잘못된 값을 가져오는 경우가 방지된다. 연산의 원자성이 보장되어, 연산이 도중에 실패할 경우 변경사항이 Commit되지 않는다. 위의 속성이 보장되기 때문에, 해당 메서드를 실행하는 도중 메서드 값을 수정/삭제하려는 시도가 들어와도 , 값의 신뢰성이 보장된다. 또한, 연산 도중 오류가..
1-3. JPA기초 Member.java / Food.java / Orders.java Restaurant.java 1. foods 리스트 생성 및 saveAll로 저장 2. members 리스트 생성 및 saveAll로 저장 3. memberRepository에서 findMembers변수로 findAll로 출력(저장된 것 확인) 4. foodRepository에서 findFoods변수로 findAll로 출력(저장된 것 확인) 5. orderList 리스트 생성 및 saveAll로 저장 6. ordersRepository에서 orderList변수로 findAll로 출력(저장된 것 확인) - for문으로 사람&음식 하나하나 출력 7. memberRepository에서 samsik변수로 findById로 삼..
배운점 Entity란? Entity 클래스는 DB의 테이블에 존재하는 Column들을 필드로 가지는 객체를 말한다. Entity는 DB의 테이블과 1대 1로 대응된다. JPA를 사용할 때 Entity 클래스에는 @Entity 어노테이션을 붙여서 Entity임을 명시해 줘야 하며, 내부의 필드에는 @Column, @Id 어노테이션 등을 사용한다. Entity는 외부에서 최대한 Entity의 Getter를 사용하지 않도록 내부에 로직을 구현하는데, 이 때 Domain 로직만 구현하고 Presentation 로직은 구현하지 않는다. Entity의 Getter 사용을 최대한 피하라고 했지만, 기본적으로 Entity를 만들 때 Getter는 만들어줘야 한다. 그런데 이동욱님이 쓰신 책을 보니, Entity 클래스..