묻고 답해요
164만명의 커뮤니티!! 함께 토론해봐요.
인프런 TOP Writers
-
해결됨실전! 스프링 부트와 JPA 활용1 - 웹 애플리케이션 개발
null 값 부분에서 오류를 못 찾겠습니다.
안녕하세요~~!! 김영한 선생님!! 강의를 듣다가 해결이 되지 않아서 질문 하나 드리겠습니다. <질문> ItemRepository 부분의 save 메소드 안에 Item.getId() == null이 "Operator '==' cannot be applied to 'long', 'null'"오류 메세지가 나옵니다. 항상 좋은 강의로 보답 해주셔서 감사합니다. 코로나 조심하시고 다음 강의 기대하겠습니다.
-
해결됨실전! 스프링 부트와 JPA 활용2 - API 개발과 성능 최적화
내부 클래스 질문
안녕하세요 선생님! 바쁘신데 이곳저곳 여러번 질문드려 죄송합니다. 강의를 복습하다가 정말 궁금한게 생겨서요.. Request Dto는 인자로 받아야돼서 테스트같은 곳에서 직접 생성해야하 되기 때문에 static으로 선언했고, Response Dto 같은 경우에는 그럴 필요가 없기 때문에 non-static으로 선언했다고 이해했습니다. 그런데 이런 경고가 뜨길래 찾아봤더니 이펙티브 자바에서 메모리 문제나 gc 문제 떄문에 바깥 인스턴스에 접근할 일이 없다면 무조건 static을 붙여서 정적멤버 클래스로 만들라고 되어있습니다. 실제 프로젝트나 실무에서는 reponse dto처럼 외부에서 직접 생성할 일이 없어도 static inner class로 선언해야 될까요? 정말 감사합니다.
-
미해결실전! 스프링 부트와 JPA 활용1 - 웹 애플리케이션 개발
@Transactional을 Service에서 처리하는 이유?
@Transact ional의 사용 이유에 대해서는 이해가 되었습니다만, 왜 굳이 Service에서 그 처리를 해주는지 이유를 모르겠습니다. 개인적인 생각으로는 직접적으로 em을 사용하는 Repository에서 해주는 게 더 적절하지 않을까 싶습니다. Service에서 사용해야만 하는 특별한 이유가 있을까요?
-
미해결실전! 스프링 데이터 JPA
데이터 중심 테이블 설계와 객체 중심의 테이블 설계
안녕하세요 김영한 스승님. JPA를 공부하다가 갑자기 궁금한게 생겨서 질문드립니다. 객체 중심의 테이블 설계와 데이터 중심의 테이블 설계가 차이점이 어떤것인가요? RDB도 객체처럼 테이블을 만들 수 있는데 그러면 굳이 객체중심으로 테이블을 설계할 필요가 없는거 아닌가요? 이 부분이 너무 헷갈려서 질문드렸습니다...
-
해결됨스프링 입문 - 코드로 배우는 스프링 부트, 웹 MVC, DB 접근 기술
Test method 접근제어자 질문드립니다.
안녕하세요. 강의를 듣던 중 테스트 메소드 접근 제어자에 궁금한점이 생겨서 질문드립니다. [회원 리포지토리 테스트] @Test public void save() { ... } [서비스 테스트] @Test void join() { ... } 이전 회원 리포지토리 테스트 코드에서는 위 코드와 같이 public로 선언했었지만, 이번 강의에서 Create Test 단축키로 생성한 테스트 메소드들은 public가 아닌 default로 선언되었습니다. default로 메소드를 선언했을 때 테스트를 수행하는데 문제가 없었는데 강의 코드에서 public으로 메소드를 선언하는 이유는 무엇인가요?
-
해결됨스프링 입문 - 코드로 배우는 스프링 부트, 웹 MVC, DB 접근 기술
Optional 사용 방법에 대해서 질문드립니다.
1) Optional<Member> result = memberRepository.findByName(member.getName()); 2) Member result = memberRepository.findByName(member.getName()).get(); 1. 위 코드에서 2번의 방법보다 1번 같은 사용법을 권장한다고 하셨습니다. 1) memberRepository.findByName(member.getName()) .ifPresent( m -> { throw new IllegalStateException("이미 존재하는 회원입니다."); }); 2) Optional<Member> result = memberRepository.findByName(member.getName()); result.ifPresent( m -> { throw new IllegalStateException("이미 존재하는 회원입니다."); }); 2. 또한 바로 위의 코드에서도 2번의 방법보다 1번의 방법 사용을 권장한다고 말씀하셨습니다. 위 방법들이 권장되는 이유가 궁금합니다. 또 권장되는 Optional 사용법 같은게 따로 문서로 존재하는건가요?
-
미해결실전! 스프링 부트와 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 두 개념에 혼동이 와서... 위 질문에 답변해주시면 감사하겠습니다!
-
미해결실전! 스프링 데이터 JPA
페이징 질문
안녕하세요 선생님! 강의를 듣다가 궁금한게 생겨 몇 가지 질문드립니다. 1. @Query를 이용해서 jpql 페치조인을 한 경우, 페이징을 하려할때 다음과 같은 에러가 뜹니다. @Query("select m from Member m join fetch m.team") Page<Member> findFetchJoinTeam(Pageable pageable); @Testvoid member(){ Team teamA = teamRepository.save(new Team("teamA")); memberRepository.save(new Member("member1", 40, teamA)); memberRepository.save(new Member("member2", 40, teamA)); memberRepository.save(new Member("member3", 40, teamA)); PageRequest pageRequest = PageRequest.of(0, 3, Sort.by(Sort.Direction.DESC, "username")); Page<Member> fetchJoinTeam = memberRepository.findFetchJoinTeam(pageRequest);} Failed to load ApplicationContext java.lang.IllegalStateException: Failed to load ApplicationContext Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'memberRepository' defined in com.example.forq.MemberRepository defined in @EnableJpaRepositories declared on JpaRepositoriesRegistrar.EnableJpaRepositoriesConfiguration: Invocation of init method failed; nested exception is java.lang.IllegalArgumentException: Count query validation failed for method public abstract org.springframework.data.domain.Page com.example.forq.MemberRepository.findFetchJoinTeam(org.springframework.data.domain.Pageable)! paging에서 count 부분이 문제인것 같은데 entitygraph로 하면 잘 돼서 제가 뭔가를 놓친건지 궁금합니다 public interface MemberRepository extends JpaRepository<Member, Long> { @Override @EntityGraph(attributePaths = {"team"}) Page<Member> findAll(Pageable pageable);} 2. where 등으로 필터링을 하지 않을떄는 countQuery를 분리해서 최적화를 하면된다고 하셨는데 만약 select m from Member m join m.team t where t.name=:name ”같이 조인 대상에 필터링을 하는 경우에는 어떻게 최적화를 할 수 있는지 궁금합니다. 감사합니다!
-
미해결스프링 입문 - 코드로 배우는 스프링 부트, 웹 MVC, DB 접근 기술
Autowired 질문드립니다.
안녕하세요 ^^ 항상 강의 감사하게 듣고 있습니다! @Autowired public MemberController(MemberServcie service) {} 생성자 방식으로 주입할때 생성자 함수위에 autorwired를 생략해도 동작하던데 실무에서는 생략을 많이 하나요? 그리고 생략을 한다면 설명을 위해서 작성을 하신건가요?
-
해결됨실전! 스프링 데이터 JPA
즐겁게 듣겠습니다~~~
어느덧 여기까지 왔어요 ㅎㅎ 이번 강의도 즐겁게 듣겠습니다. 항상 잘 듣고있어요
-
미해결실전! 스프링 부트와 JPA 활용1 - 웹 애플리케이션 개발
주문내역 검색 form 관련해서 질문입니다...
안녕하세요 강의 정말 재미있게 스프링핵심 원리, JPA 잘 듣고 있습니다. 주문 목록 검색 form 태그에 action 속성이 없는데 submit을 할경우 어떤식으로 작동하는지 이해가 잘 안가여 질문드립니다.
-
미해결스프링 입문 - 코드로 배우는 스프링 부트, 웹 MVC, DB 접근 기술
thymeleaf가 URI is not registered가 뜹니다
thymeleaf가 URI is not registered가 뜹니다 스프링부트 생성 때 의존성추가 했고 마켓플레이스에서는 thymeleaf를 검색해도 나오지 않는데 무엇을 잘못했을까요?ㅠㅠ 스프링은 2.4.3 자바 11입니다
-
미해결실전! 스프링 부트와 JPA 활용1 - 웹 애플리케이션 개발
공부를 하면서..
spring 핵심 원리에서 배웠던 DI, interface를 이용해서 추상화하는 방식이 사용되고 있지않고. 그냥 private final ItemService itemService 이런식으로 진행하고 계시는데 jpa 강의라서 이렇게 간단하게 설계 하시는건가요?? 실무에서 프로젝트 사이즈가 커지다보면 자연스레 추상화하게 되나요?? 질문 자체가 이상했으면 죄송합니다..
-
해결됨스프링 입문 - 코드로 배우는 스프링 부트, 웹 MVC, DB 접근 기술
@repository에 관하여
안녕하세요 @Repository가 MemberRepository를 구현한 MemoryMemberRepository에 붙어있는데요 만약 MemberRepository를 구현한 DBMemberRepository라는 클래스가 하나 더있고 여기에도 @Repository가 붙어있다면 MemberService에서는 어떤 Repository를 주입시켜주나요? 읽어주셔서감사합니다.
-
해결됨스프링 입문 - 코드로 배우는 스프링 부트, 웹 MVC, DB 접근 기술
Autowired순서
안녕하세요 강의를 듣던 중 궁금한점이 생겨 질문드리게되었습니다. MemberService에서 @Autowired 를 통해 MemberRepository를 주입시키는 과정에서 MemberRepository가 MemberService 보다 먼저 빈등록이 되어있다면 문제가 없겠지만 MemberRepository가 MemberService 보다 늦게 빈등록이 될경우 문제가 생길것 같은데 어떻게 작동하나요? 즉, 빈등록되는 순서가 궁금합니다. 읽어주셔서 감사합니다
-
미해결스프링 입문 - 코드로 배우는 스프링 부트, 웹 MVC, DB 접근 기술
안녕하세요 강사님
안녕하세요 강사님 질문있습니다. 강의 목록 중에 "실전! 스프링 웹 MVC 출시 예정 - 2월" 인 부분이 있는데 언제 나오는지 알 수 있을까요??
-
해결됨실전! 스프링 부트와 JPA 활용2 - API 개발과 성능 최적화
양방향 연관관계일 때 한쪽을 끝는거에 대해 질문드립니다.
@JsonIgnore 어노테이션을 사용하면 지금 상태로는 꼭 하이버네이트5모듈을 사용해야 하는거죠? 일단 지금은 그렇게 알고있으면 될까요? 감사합니다.
-
해결됨실전! 스프링 부트와 JPA 활용2 - API 개발과 성능 최적화
모든 주문리스트 조회하는 타임리프 올려봅니다.
<!DOCTYPE HTML><html xmlns:th="http://www.thymeleaf.org"><head th:replace="fragments/header :: header"></head><body><div class="container"> <div th:replace="fragments/bodyHeader :: bodyHeader"></div> <div> <div> <form th:object="${orderSearch}" class="form-inline"> <div class="form-group mb-2"> <input type="text" th:field="*{memberName}" class="form- control" placeholder="회원명"/> </div> <div class="form-group mx-sm-1 mb-2"> <select th:field="*{orderStatus}" class="form-control"> <option value="">주문상태</option> <option th:each="status : ${T(jpabook.jpashop.domain.OrderStatus).values()}" th:value="${status}" th:text="${status}">option </option> </select> </div> <button type="submit" class="btn btn-primary mb-2">검색</button> </form> </div> <table class="table table-striped"> <thead> <tr> <th>#</th> <th>회원명</th> <th>대표상품 이름</th> <th>대표상품 주문가격</th> <th>대표상품 주문수량</th> <th>상태</th> <th>일시</th> <th></th> </tr> </thead> <tbody> <span th:each="item : ${orders}"> <tr th:each="orderItem : ${item.orderItems}"> <td th:text="${orderItem.item.id}"></td> <td th:text="${item.member.name}"></td> <td th:text="${orderItem.item.name}"></td> <td th:text="${orderItem.orderPrice}"></td> <td th:text="${orderItem.count}"></td> <td th:text="${item.status}"></td> <td th:text="${item.orderDate}"></td> <td> <a th:if="${item.status.name() == 'ORDER'}" href="#" th:href="'javascript:cancel('+${orderItem.order.id}+')'" class="btn btn-danger">CANCEL</a> </td> </tr> </span> </tbody> </table> </div> <div th:replace="fragments/footer :: footer"></div></div> <!-- /container --></body><script> function cancel(id) { var form = document.createElement("form"); form.setAttribute("method", "post"); form.setAttribute("action", "/orders/" + id + "/cancel"); document.body.appendChild(form); form.submit(); }</script></html> 구글 뒤져가면서 왜 이중 each를 쓰는데 인텔리제이가 빨간줄 긋지...싶었는데 tr을 두번으로 each하면 안되나봅니다. ㅠㅠ 바깥의 each를 span태그로 바꿔주니까 잘되는거같네요! 혹시나 막히시는 분들은 참고하셔요! 이거 만드는데 1시간넘게걸렸네요 .. ㅠㅠㅠㅠㅠㅠ
-
미해결실전! 스프링 부트와 JPA 활용1 - 웹 애플리케이션 개발
DTO 사용에대해 궁금합니다.
안녕하세요 영한님. 항상 좋은강의 보면서 이미 완강을 하였지만 궁금한점이 이 강의내용에 해당되는것 같아 질문을 남깁니다. 컨트롤러에서 (API) 개발을 할때 Entity를 바로 접근하지 말고 DTO를 권장하셔서 DTO를 사용하던 찰나에 문제가 생겼습니다. Entity에 Setter를 사용하는건 지양한다고 하셔서 생성자로 값을 넣어주고 있는데 DTO에서도 값을 생성자로 넣어줘야 하나요? 백을 먼저 개발하고 프론트를 개발하기위해 타임리프로 하고 있는데 DTO 를 생성자로 만들어 놓으니 값을 계속 못받아와서요. 한참 헤매다가 설마 하고 LOMBOK @Setter 로 하니 값이 넘어오더라고요. DTO는 Setter로 하여도 문제가 없을까요? 제 생각에도 DTO는 단순 값을 전달 받는 Form(?)이라고 생각되어 Entity에서의 Setter를 지양해야하는 문제에 와는 달리 큰 영향은 없을 것 같아서요. 감사합니다.!
-
미해결실전! 스프링 부트와 JPA 활용2 - API 개발과 성능 최적화
API 설계시 게시글과 댓글
안녕하세요 강사님. http, 스프링, jpa 모두 강사님 수업을 듣고 인생 첫 스프링 프로젝트로 게시판 API를 구현 해 보려고 하는 대학생입니다. 그래서 현재 아래와 같이 요청경로와 요청법, 응답 본문, 에러응답 등을 문서화 하고 있습니다. 경로를 올바르게 설계했는지는 잘 모르겠지만, 게시글 정보 반환시 게시글과 댓글관계에 대해 궁금해서 질문 드립니다. GET /boards/{board-id}/posts/{post-id} 으로 요청시 게시글의 작성자id, 제목, 내용등이 반환되는데, 댓글들의 목록도 포함시킬지 고민입니다. 보통 게시글이 댓글을 가지고 있으니깐 처음에는 댓글 요청경로를 빼고 게시글 요청에 당연히 포함시켜야 하지 않나? 생각을 했습니다.그런데 댓글에 페이징 기능까지 넣으려고 생각하니깐 게시글과 댓글을 분리해서 게시글정보와 댓글 정보를 각각 받아오도록 하는게 좋을 것 같다는 생각이 들었는데, 혹시 현업에서도 댓글과 게시글은 분리해서 각각 따로 가져오게 설계를 하는지 궁금합니다. 추가적으로, 이건 강사님의 HTTP수업과 관련된 질문이긴한데 게시글,유저 등록같은 POST /boards/{id}/posts 의 201 응답 Location 헤더에 생성된 자원의 주소(예를들어 http://localhost:8080/boards/1/posts/1)가 어차피 포함되어 오는데, 응답 본문에 생성된 자원(게시글)을 다시 보내주는게 RESTful API에 더 가까운가요? 생각해보면 생성된 자원의 위치를 어차피 알려주는데 의미없는 오버헤드인 것 같더라구요.