묻고 답해요
141만명의 커뮤니티!! 함께 토론해봐요.
인프런 TOP Writers
-
해결됨실전! 스프링 부트와 JPA 활용1 - 웹 애플리케이션 개발
Entity 생성시 다른 애그리거트의 정보/로직이 필요한 경우 생성 방식의 선택 기준
안녕하세요. 이번 강의 내용에서 추가적인 요구사항을 적용해보는 중, 설계상 궁금증이 생겨 질문하게 되었습니다. jpashop에서는 환불제도 악용 회원의 주문을 일정 기간동안 금지할 수 있다는 요구사항을 추가했습니다. 이 변경된 요구사항을 위해, MemberStatus라는 VO를 Member 클래스에 추가했습니다. 결과적으로, Order 클래스를 생성함에 있어서 MemberStatus의 로직(다른 애그리거트의 Value Object)을 필요로 합니다. 이 때, 선택할 수 있는 생성 방식이 여러개가 떠올라서, 이들의 선택 기준에 대한 조언을 듣고 싶습니다. 첫번째 방식. 정적 팩토리 메서드의 매개변수로 추가 첫번째 방식은 생성시 필요한 정보를 가진 객체(MemberStatus)들을, 정적 팩토리 메서드의 매개변수로 전달합니다. 선택 기준은 객체(Order)를 생성함에 있어서, 특정 객체(MemberStatus)가 필요함을 명시적으로 알릴 수 있습니다. 생성로직을 해당 클래스가 전적으로 제어하는 것이 생성 로직을 한 곳에 더 응집시킬 수 있습니다. 이 두가지를 고려했습니다. 이 방식에서는 회원 차단에 따른동작 분기는 정적 팩토리 메서드 내에서 이루어집니다. 다만, Order를 생성하는데 있어서 MemberStatus 이외에도 협력해야 할 애그리거트들이 많이 존재하는 경우 Order 클래스가 너무 많은 의존성을 가지게 될 수 있다는 점이 우려됩니다. 두번째 방식. 생성을 위한 정보/로직을 가지고 있는 클래스가 생성을 담당 선택 기준은 Member가 Order를 생성하기 위한 로직(회원 차단 여부)을 제공합니다. 위 내용을 고려했습니다. 이 방식에서는 검증 통과 여부에 따른 동작 분기는 Member의 메서드 내에서 이루어집니다. 다만, 이 방식은 Member —> Order로의 불필요한 의존성을 만들어낼 수 있다고 우려했습니다 특히, 생성에 대한 책임을 맡는다는 것은 내부에 어떤 데이터를 가지고 있는지 전부 알아야 한다는 점에서 생각보다 과도한 의존성을 부여하고 있는 것 같습니다. 또한 협력해야 할 애그리거트가 많아질 수록, Member가 생성과 관련된 다른 클래스들에 대한 많은 의존성을 감당해야 한다는 점이 우려됩니다. 세번째 방식. 애그리거트를 생성하는 Domain Service를 만든다. 선택기준은 많은 의존성을 가져야 하는 생성 로직을 서비스에 담음으로서, 엔티티가 불필요한 의존성을 가지는 것을 방지합니다. 위 내용을 고려했습니다. 다만, 조금만 복잡해져도 도메인 서비스를 사용하고자 하는 유혹이 생겨서, 자칫하면 다른 로직들도 Domain Service로 구현해, Entity 자체의 응집성이 작아지는게 아닌가 우려스럽습니다. 질문 내용 정리 1. 각 생성 방식을 선택함에 있어서 미흡한 선택 기준에 대해서 조언 해주 실 수 있나요? 2. 또 첫번째, 두번째 방식이 우려하는 사항들은 현재의 사례에서는 잘 드러나지 않는 '잠정적인' 우려사항들인데, 실제로 이 우려사항들이 나타나기 전까지는 가장 간단한 구현(첫번째 혹은 두번째)을 그대로 사용해도 될까요?
-
해결됨실전! 스프링 부트와 JPA 활용1 - 웹 애플리케이션 개발
질문
1. id 값이getmapping으로 넘어오는 것도 관계가 궁급합니다. itemList.html에도 특정하게 id값을 넘겨달라 라고 보이는 문구도 없어보이는데 id값만 인자로 지정해서 넘어오는 것도 궁금합니다. 이어지는 부분이 없다고생각하는데 이런건 requestparam으로 받는게 맞지 않을까요? public String updateItemForm(@PathVariable("itemId") Long id, Model model){ Book one = (Book) itemService.findOne(id); 선생님 이부분에서 items/createItemForm 에서 정보를 입력받으면 submit버튼을 누르는 순간 postmapping 으로 값들이 담겨져서 밑의 코드처럼 bookform 형식의 값이담긴 form이 넘어와지게 된다고 하셨는데 booform의 클래스의 필드이름들이 html(createItemForm )태그에 타임리프 문법에 있는 name, id, isbn 등등 필드 이름과 매칭이 돼서 넘어오는줄 알았는데 bookform클래스의 필드 이름이 다르게 바껴도 값이 넘어오더라고요.... 어떻게 매칭이 되고 어떤 관계가 있어서 bookform에 잘 맞춰서 넘어오게되는지 궁금합니다. @PostMapping("/items/new")public String create(BookForm form){ Book book = new Book(); book.setName(form.getName()); book.setPrice(form.getPrice()); book.setStockQuantity(form.getStockQuantity()); book.setAuthor(form.getAuthor()); book.setIsbn(form.getIsbn()); itemService.saveItem(book); return "redirect:/";}
-
미해결실전! 스프링 부트와 JPA 활용1 - 웹 애플리케이션 개발
LOB를 위한 @OneToOne 혹은 @Basic
안녕하세요. 기본적으로 게시판을 만들 경우 LOB를 사용하게 됩니다. 그럼 Lazy를 사용하게 되는데 경험상 어떤 구조가 좋은지 알고 싶습니다. 지금까지는 @ElementCollection을 만들어서 Unique를 주어서 one to one 처럼사용을 하였습니다. 자구 눈에 거슬려서 리팩토링을 하고 싶은데 하나의 테이블에서 @Basic를 사용하는 것이 좋은지 아니면 서브 테이블을 만들고 @OneToOne 관계를 사용하는것이 좋은지 노하우를 공유하고 싶습니다. @OneToOne에서는 단방향을 사용하고 싶고 서브 테이블의 PK 컬럼은 PK이면서 FK로 설정하고 싶습니다. (즉, 메인 테이블의 PK값을 사용) 그럼, 수고하세요.
-
미해결실전! 스프링 부트와 JPA 활용1 - 웹 애플리케이션 개발
JPA 연관관계 질문드립니다.
안녕하세요. JPA 강의를 듣고 연관관계부분 실습해보다 질문드립니다. 다대다 관계는 실무에서 사용하지 않는게 좋다고 하셔서 직접 중간테이블을 만들고 카테고리테이블, 카테고리_아이템 테이블, 아이템 테이블을 만들어 아래와 같이 구현해보려 했습니다. 간단히 엔티티 코드를 요약해보았습니다. 카테고리를 눌렀을 때 해당 카테고리에 Item 리스트를 불러오고 각각의 Item들에서도 카테고리 정보를 노출하고싶은데 어떻게 해야 할지 감이 잡히질 않습니다. categoryItem의 Repository에서 쿼리문으로 조인하여 가져오는것은 매우 복잡할것같고 Item이나 Category의 엔티티 안에 메서드를 만들어서 가져와보려했는데 제 기본기가 부족해서 그런지 도저히 방법이 떠오르질 않네요. 어떤식으로 구현을 해야좋을지 대략적인 흐름을 간단히 조언해주시면 감사하겠습니다.
-
미해결실전! 스프링 부트와 JPA 활용1 - 웹 애플리케이션 개발
하나의 Repository에서 2개 이상의 서로 다른 유형의 엔터티를 반환해도 되나요?
안녕하세요. 좋은 강의 덕분에 업무에 많은 도움이 되고 있습니다. 감사합니다. ^^ 다름이아니라, 강의 예제에 나온 repository에서는 보통 한 종류의 엔터티를 반환하는데요. 예를 들면 OrderRepository 에서는 반환값이 Order, List<Order> ItemRepository에서는 Item, List<Item>을 반환합니다. 하지만 OrderRepository에서 Item, List<Item>을 반환하는 경우는 없더군요. 그런데 여러 테이블간에 조인을 거쳐 최종 조회되는 엔터티가 해당 Repository의 엔터티가 아닌 경우, 이럴 때는 어떻게 하는 게 좋을까요? 예를 들면 엔터티 간의 관계가 아래와 같을 때 Order : OrderItem = 1 : N Item : OrderItem = 1 : N Item : ItemCategory = 1 : N Category : ItemCategory = 1 : N Order Id = 100인 Item의 List<Category>를 조회하고자 하는 경우 OrderRepository에서 각 엔터티들의 조인을 거쳐 List<Category>를 반환하는 게 좋을까요? 아니면 각각의 Repository에서 필요한 엔터티를 반환받아 최종적으로 List<Category>를 찾는 것이 좋은가요? 아니면 제 3의 별도의 Repository를 만드는 것이 좋을까요? 여러개의 테이블을 조인하여 한 번의 쿼리로 데이터를 조회하는 것이 더 성능상 이점이 있을 것 같은데요 반면 Repository에서 서로 다른 유형의 엔터티를 반환해도 유지보수에 문제가 없을지 걱정이 듭니다. 김영한님의 조언 부탁드립니다.
-
해결됨실전! 스프링 부트와 JPA 활용1 - 웹 애플리케이션 개발
정적 팩토리 메서드 작성
@Entity @DiscriminatorValue("B") @Getter @Setter public class Book extends Item { private String author; private String isbn; public static Book createBook(String name, int price, int stockQuantity, String author, String isbn) { Book book = new Book(); book.setName(name); book.setPrice(price); book.setStockQuantity(stockQuantity); book.setAuthor(author); book.setIsbn(isbn); return book; } } setter들을 최대한 줄이고자 위와 같이 정적 팩토리 메서드를 작성했습니다. 그런데 결국 Book 객체를 만들기 위해선 createBook안에 setter가 필요하게 되더라구요 그래서 setter을 닫으면서 정적 팩토리 메서드를 작성하기 위한 두가지 방법이 생각났는데요 첫 번째는 생성자를 protected으로 만들어놓고 정적 팩토리 메서드에서 setter가 아닌 생성자로 객체를 생성하는 방법이고 두 번째로 setter의 접근 권한을 private으로 설정하여 정적 팩토리 메서드 안에서만 setter을 사용하도록 허가하는 방법입니다. 두 방법 중에 무엇이 더 사용하기 적합한지, 아니면 그 외에 다른 방법엔 어떤 것이 있는지 궁금합니다. /// 추가 강의를 진행하다보니 두 방법 모두 setter의 부재로 변경 감지 방법을 사용하지 못한다는 문제점이 있는 것 같습니다.. 변경 감지 강의에서의 영한님 말씀처럼 setter 대신에 비즈니스 메서드를 만들어서 변경 감지 등의 로직에서 사용하고, 정적 팩토리 메서드에서는 첫 번째 방법처럼 생성자로 객체를 생성하는 방법을 사용하려고 하는데 옳은 방법일까요?
-
미해결실전! 스프링 부트와 JPA 활용1 - 웹 애플리케이션 개발
테스트 실행 시 생성되는 로그의 DDL문에 대해 질문합니다.
안녕하세요 강사님. 테스트를 실행했을 때 강사님께서는 DDL문이 한 줄마다 줄바꿈되어 나오는데, 저는 한줄로 쭉 연결되어 나옵니다. 사실 별 건 아니지만 가독성이 떨어져서 찾아보기가 약간 힘들게 느껴져서 혹시 설정하는 방법이 있는지 여쭤봅니다 ㅠㅠ 현재 H2 버전을 1.4.199를 깔아 사용하고 있는데 이거때문일까요?
-
미해결실전! 스프링 부트와 JPA 활용1 - 웹 애플리케이션 개발
제대로 이해한 게 맞을까요? + 오타 제보 + setter 추가 질문
수정하려는 엔티티의 키가 10이라고 했을 때, 1. DB에는 아직 수정 전인 엔티티가 들어있음. 이건 영속. 2. Book book = new Book(); 한 후 BookForm의 정보들로 set해줌. 이건 그냥 함수 내에서 new로 만들었을 뿐이니 JPA가 관리하고 있지 않음. 하지만 이 book의 키값인 10은 디비에 저장되어있음. 그래서 이건 준영속. (즉, 10이란 키값을 갖는 엔티티에 대해 영속 엔티티와 준영속 엔티티가 동시에 존재하는 상황.) 3. 여기서 준영속 엔티티 book의 key값으로 검색하여 영속 엔티티 findItem을 가져오고 값을 덮어씌움. 4. 모든 작업 이후에도 book은 여전히 준영속 엔티티이므로 더이상 사용하지 않는 것이 좋음. + 5. 결국 더티체킹 메서드를 직접 만들든, em.merge()를 사용하든 내부적으로는 전부 더티체킹을 사용하여 update하는 것임. (null 업데이트 문제는 제쳐두고) 이런 흐름이 맞나요? merge의 과정보다도 merge 실행 전에 같은 키값의 영속,준영속이 동시에 존재하는 부분이 맞는지가 더 모르겠고 궁금하네요. 감사합니다!ㅡㅡㅡㅡㅡㅡㅡㅡ19:53에서 맨 윗줄에 '재'한적이다 오타 제보드립니다. ㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡ (추가질문) setter를 경계하라는 말씀을 다시 한 번 해주셨는데요. "change()처럼 엔티티에 변경 메서드를 따로 만들면 추적이 쉽다" 라는 말씀에서 이해가 좀 안 가는 부분이 있습니다. setter로 변경을 하더라도 그 setter명으로 역추적하면 변경지점이 어디인지 알 수 있는 것 아닌가요? 혹시 여러 엔티티에서 같은 이름의 멤버변수를 가지는 경우엔 setter이름도 같아져서 찾기 어렵다는 말씀이신가요?
-
해결됨실전! 스프링 부트와 JPA 활용1 - 웹 애플리케이션 개발
null 값 부분에서 오류를 못 찾겠습니다.
안녕하세요~~!! 김영한 선생님!! 강의를 듣다가 해결이 되지 않아서 질문 하나 드리겠습니다. <질문> ItemRepository 부분의 save 메소드 안에 Item.getId() == null이 "Operator '==' cannot be applied to 'long', 'null'"오류 메세지가 나옵니다. 항상 좋은 강의로 보답 해주셔서 감사합니다. 코로나 조심하시고 다음 강의 기대하겠습니다.
-
미해결실전! 스프링 부트와 JPA 활용1 - 웹 애플리케이션 개발
@Transactional을 Service에서 처리하는 이유?
@Transact ional의 사용 이유에 대해서는 이해가 되었습니다만, 왜 굳이 Service에서 그 처리를 해주는지 이유를 모르겠습니다. 개인적인 생각으로는 직접적으로 em을 사용하는 Repository에서 해주는 게 더 적절하지 않을까 싶습니다. Service에서 사용해야만 하는 특별한 이유가 있을까요?
-
미해결실전! 스프링 부트와 JPA 활용1 - 웹 애플리케이션 개발
변경 감지와 cascade 질문
안녕하세요, 공부하다 cascade 옵션과 변경 감지에 혼동되는 점이 있어 질문 드립니다. 주문 생성 메서드(order)의 경우, Order -> OrderItem / Order -> Delivery가 Cascade 설정이 되어 있어 orderRepository.save(order)만 하더라도 연관된 OrderItem과 Delivery가 각각 Insert된다고 이해했습니다.(remove, detach 등등 모두 동일) 주문 취소 메서드(cancelOrder)를 보면 orderId를 통해 order를 조회하고(조회된 order는 영속 상태), order.cancel()시 orderItem.cancel()과 그 안의 item.addStock()을 통해 변경감지가 되어 order와 item의 update 쿼리가 실행된다고 하셨습니다. 여기서 제가 헷갈리는 부분은 주문 취소시 item이 변경감지가 되어 update쿼리가 실행되는 부분인데요. item.addStock()을 통해 item의 update 쿼리가 실행됐다는 것은 item이 영속성 컨텍스트에 영속상태가 되었다는 것을 뜻하는데, 단순히 order를 orderRepository로 조회를 하게 되면 order와 연관된 모든 엔티티들이 영속상태가 되는 것인가요? (order 한 개 조회 시-> orderItem... 영속-> item... 영속) 위의 과정이 맞다면 연관된 여러 엔티티의 변경감지는 cascade 설정과는 무관하게 엔티티 조회 시 관련된 엔티티는 모두 영속화 되는 것인지 궁금합니다. (order -> orderItem -> item 의 변경감지를 위해 order->orderItem cascade.ALL 설정 & orderItem->item cascade.ALL 설정이 되어야 orderRepository를 통해 order 조회 시 하위 엔티티들이 모두 영속화 되는 것인가?) 만일 연관관계가 있는 엔티티들이 cascade설정이 되어있어야 모두 영속성 상태로 변하는 것이라면 order->orderItem에는 cascade.ALL 설정이 있으나 orderitem->item에는 cascade.ALL 설정이 없는데 order -> orderItem -> item 순으로 변경감지가 되는지 궁금합니다. 질문이 좀 길어졌는데요 변경감지와 cascade 두 개념에 혼동이 와서... 위 질문에 답변해주시면 감사하겠습니다!
-
미해결따라하며 배우는 노드, 리액트 시리즈 - 영화 사이트 만들기
회원가입이 안되는데 어떻게 수정해야될까요?
console 창 가져온건데 서버-클라이언트 코드가 달라 변경도 해보았는데 안되서 어떻게 해야할지 모르겠습니다ㅠㅠ 도와주세요ㅜㅜ 서버쪽코드 const request = axios.get(`${USER_SERVER}/auth`) 클라이언트코드 router.get("/auth", auth, (req, res) => {
-
미해결실전! 스프링 부트와 JPA 활용1 - 웹 애플리케이션 개발
주문내역 검색 form 관련해서 질문입니다...
안녕하세요 강의 정말 재미있게 스프링핵심 원리, JPA 잘 듣고 있습니다. 주문 목록 검색 form 태그에 action 속성이 없는데 submit을 할경우 어떤식으로 작동하는지 이해가 잘 안가여 질문드립니다.
-
미해결실전! 스프링 부트와 JPA 활용1 - 웹 애플리케이션 개발
공부를 하면서..
spring 핵심 원리에서 배웠던 DI, interface를 이용해서 추상화하는 방식이 사용되고 있지않고. 그냥 private final ItemService itemService 이런식으로 진행하고 계시는데 jpa 강의라서 이렇게 간단하게 설계 하시는건가요?? 실무에서 프로젝트 사이즈가 커지다보면 자연스레 추상화하게 되나요?? 질문 자체가 이상했으면 죄송합니다..
-
미해결실전! 스프링 부트와 JPA 활용1 - 웹 애플리케이션 개발
DTO 사용에대해 궁금합니다.
안녕하세요 영한님. 항상 좋은강의 보면서 이미 완강을 하였지만 궁금한점이 이 강의내용에 해당되는것 같아 질문을 남깁니다. 컨트롤러에서 (API) 개발을 할때 Entity를 바로 접근하지 말고 DTO를 권장하셔서 DTO를 사용하던 찰나에 문제가 생겼습니다. Entity에 Setter를 사용하는건 지양한다고 하셔서 생성자로 값을 넣어주고 있는데 DTO에서도 값을 생성자로 넣어줘야 하나요? 백을 먼저 개발하고 프론트를 개발하기위해 타임리프로 하고 있는데 DTO 를 생성자로 만들어 놓으니 값을 계속 못받아와서요. 한참 헤매다가 설마 하고 LOMBOK @Setter 로 하니 값이 넘어오더라고요. DTO는 Setter로 하여도 문제가 없을까요? 제 생각에도 DTO는 단순 값을 전달 받는 Form(?)이라고 생각되어 Entity에서의 Setter를 지양해야하는 문제에 와는 달리 큰 영향은 없을 것 같아서요. 감사합니다.!
-
미해결실전! 스프링 부트와 JPA 활용1 - 웹 애플리케이션 개발
안녕하세요 제가 이해한게 맞는지 애매합니다.
저는 기존에 spring과 mybatis를 사용하다 강의를 듣게되어서 service와 mapper의 역할이 딱 나뉘어진 코드에 익숙했는데 엔티티에 로직이 들어가니 조금 당황스럽네요 ㅎㅎㅎ... 각설하고 다른 질문들을 보았지만 명쾌하게 이해되지는 않아서 강의 내용과 제가 생각한 내용들로 이해해봤는데 맞는지 확신이 안서서 질문드려요 1. 회원 파트와 주문파트의 엔티티 구성방식이 다른 것(생성메서드,비즈니스 로직등의 유무) 은 회원은 기능구현시 타 엔티티와 상호작용하는 부분이 없어 간단한 구현이라는 판단아래에 별 로직이 없고 주문파트는 상호작용하는 부분(주문 취소시 수량 복구, 주문이라는 행위시 연관되는 엔티티정보들) 이 있기에 많은 로직이 있다는 걸로 받아들이면 될까요? 2. 주문 취소의 경우 서비스 부분에 들어가는게 맞다고 생각했는데 엔티티에 구현하셔서 질문들을 찾아보니 취소가 되기 위해선 주문엔티티의 배달상태의 정보가 바뀌고,수량 복구가 되어야하고 해당하는 정보들이 가장 가까운 Order와 OrderItem엔티티에서 로직을 수행한다는 말씀이시고 이게 객체지향 스럽다? 라고 이해하면 될까요?
-
미해결실전! 스프링 부트와 JPA 활용1 - 웹 애플리케이션 개발
안녕하세요, EntityManager에 대해 궁금한 점이 있어 질문 남깁니다.
JPA 기본편 강의와 같이 듣고 있습니다. 좋은 강의 항상 감사드립니다. (질문 도중 제가 잘못 이해 하고 있는 부분이 있다면 말씀주시기 바랍니다.) 다름 아니라 EntityManager는 요청이 들어올 때 생성되어 사용됬다가 해당 요청이 마무리 되면 삭제된다고 이해 하고 있습니다. 근데 @Repository를 DI를 통해 생성할 때 @RequiredArgsConstructor 를 통해 EntityManager도 생성해줍니다. 그럼 이 EntityManager 인스턴스는 @RequiredArgsConstructor 위 어노테이션으로 인해 필요할 때 마다 그 때 그 때 생성된다고 볼 수 있을까요? 아니면 싱글톤 객체 안에 필드임으로 그 때 그 때 새로운 값을 할당 받는건가요? 감사합니다, 좋은 하루 되세요~
-
해결됨실전! 스프링 부트와 JPA 활용1 - 웹 애플리케이션 개발
JPA update
안녕하세요 . 일부 field 에 대한 update를 할때, 기존 entity의 모든 field를 꼭 불러와서 update를 해야하나요? 감사합니다 !!
-
미해결실전! 스프링 부트와 JPA 활용1 - 웹 애플리케이션 개발
generated 폴더 자동 생성이 됩니다.
PDF 파일에서 IntelliJ Gradle 대신에 자바 직접 실행 항목에 적힌 설명처럼 IntelliJ IDEA 변경하고 프로그램 실행시에 /src/main 하위에 generated 폴더가 자동으로 생기는데 왜 생기는건가요?? 안 생기게 못하나요?? 환경 스프링 부트 2.4.2 인텔리제이 얼티메이트 2020.3.1
-
해결됨실전! 스프링 부트와 JPA 활용1 - 웹 애플리케이션 개발
어노테이션 관련 질문드립니다.
7분 즘에 MemberRepository 클래스르 만들고 @PersistenceContext 어노테이션을 private EntityManager em; 에 붙였는데 원래 정석대로라면 팩토리를 만들고 그걸로 엔티티매니저를 반환받는거였는데 이 어노테이션으로 그 과정을 스킵한다고 봐도 되나요? 팩토리 만들 때 마다 비용이 많이 소모된다고 알고있는데 이 어노테이션도 똑같이 팩토리를 한번만 만들고 그 팩토리로 엔티티매니저를 반환하나요? 그렇다면 이 과정을 알고 있다는 전제 하에 그냥 간단하게 @Autowired 같은 거라고 보면 될까요 ㅎㅎ...