@Test public void 상품주문_재고수량초과 () throws Exception { //Given Member member = createMember() ; Item item = createBook( "시골 JPA" , 10000 , 10 ) ; //이름, 가격, 재고 int orderCount = 11 ; //재고보다 많은 수량 //When assertThrows (NotEnoughStockException. class, () -> { orderService .order( member .getId() , item .getId() , orderCount ) ; }) ; //Then fail ( "재고 수량 부족 예외가 발생해야 한다." ) ; } 안녕하십니까. 김영한님의 강의를 열심히 수강중인 학생입니다. Junit5에 대해 질문이 있어 글을 올립니다. 제가 Junit5를 배워보려고 강의 진행중 Junit4 대신 Junit5 를 써보았습니다. 그런데 Assertions.fail 때문에 위 코드가 자꾸 실패가 뜨더라고요. 제가 생각한 로직은 김영한님 강의에서 처럼 Assertions.assertThrows 안의 로직에서 예외를 던지면 fail까지 내려오지 않고 그대로 테스트가 성공으로 종료되며, 만약 예외를 던지지 않으면 fail까지 내려와 테스트 실패가 나오는 것이었습니다. 어떻게 코드를 수정하면 될까요? ------------------------------------------------------------------------------------------------------------------ 설명이 부족한 것 같아 추가로 남깁니다. 위 코드는 재고보다 많은 수량이 입력됐을때 예외를 제대로 내뱉는지 확인하기 위한 테스트입니다. 만약 예외를 제대로 뱉었다면 김영한님 강의에서처럼 fail() 까지 안넘어가고 assertThrows 에서 테스트가 종료되고 성공으로 반환되어야 했습니다. 그런데 위 코드에서는 코드 진행이 fail까지 내려가고 그대로 실패가 뜨더라고요. Service, repository와 같은 기타 다른 연관 코드들은 김영한님 코드와 동일하게 작성하였으며, fail을 주석처리하고 위 테스트를 돌렸을 경우 성공처리가 됩니다. 상기 목적을 달성하려면 위 코드를 어떻게 수정하면 될까요?
em.detach() 나 em.clear()를 해줄시, 프록시 객체가 영속성 컨텍스트에서 지워져서 이후, 프록시 객체의 메서드를 호출했을때 Lazy 예외가 발생합니다. 하지만 수업에서 하는 것처럼 em.close()를 해도 예외가 발생하지 않고, 실제 객체가 영속성 컨텍스트에 올라와 동작합니다.
안녕하세요. 잘 듣고 있습니다. 현재 제가 사용하는 인텔리J에서는 WebSecurityConfigureAdapter.java 디버깅이 안되는데.. (찾아보니 외부 Jar 파일을 디버깅하려면 remote 디버깅을 해야한다는데 이방법으로 하신건가요? ) 인텔리J에서 어떤식으로 설정을 해야 강사님이 하는 것과 같이 디버깅이 되는건가요?
안녕하세요, 김영한 강사님. 페치 조인 시 페이징을 시도하면 메모리에서 프로세싱이 이루어지기 때문에 Out of Memory가 일어날 수 있다고 말씀주셨는데요. 이 이유가 정렬 시 추가적인 메모리 공간을 사용하기 때문인가요? 대량의 데이터를 페이징 없이 쿼리하면 메모리를 거치지 않고 결과값을 내려주나요? 페이징 없이 쿼리를 하더라도 메모리를 통한다면 수 많은 데이터를 쿼리하더라도 Out of Memory가 일어날수 있는게 아닌가 싶어서요. 혹시 제가 디비 쿼리 원리를 잘못 이해하고 있는걸까요. 감사합니다.
안녕하세요. 핵심원리를 듣고 이번 강의를 들으면서 배운 것을 적용하려고 시도해보았습니다. Service interface와 Repository interface를 생성하여, componentscan을 사용하여 빈을 등록하려고 했습니다. 기존 service와 repository를 Impl로 바꾸어 @Component 어노테이션을 붙여 의존관계를 자동 주입하려고 했습니다. ``` @Component @Transactional public class MemberServiceImpl implements MemberService { private final MemberRepository memberRepository ; @Autowired public MemberServiceImpl (MemberRepository memberRepository) { this . memberRepository = memberRepository ; } ``` @Component public class MemoryMemberMemberRepository implements MemberRepository { @PersistenceContext private final EntityManager em ; @Autowired public MemoryMemberMemberRepository (EntityManager em) { this . em = em ; }@Configuration @ComponentScan ( excludeFilters = @ComponentScan.Filter (classes= Configuration . class ) ) public class AppConfig { } @Test public void 회원가입 () throws Exception{ //given AnnotationConfigApplicationContext ac = new AnnotationConfigApplicationContext(AppConfig. class ) ; 해당 코드를 테스트를 시도하였지만 No qualifying bean of type 'javax.persistence.EntityManager' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {} 이라는 오류가 발생하였습니다. 개념이 많이 부족하여 질문을 제대로 했는지도 정확하지않고, 해당 오류가 왜 나는지 잘 모르겠습니다 ㅠㅠ
강의를 듣고 질문들을 보면서 저나름 정리한 내용인데 확실히 맞는지가 궁금합니다. ! 1. Test에서 데이터변경이 일어나기에 @Transactional 에너테이션으로 트랜잭션시작을 지정한 상황에서 MemberService의 join메서드가 실행되면 join메서드도 @Transactional 에너테이션이 있어도, 동일한 트랜잭션으로 인식한다. (트랜잭션 내부의 트랜잭션이여도 동일한 트랜잭션) 2. 그렇다면 MemberServiceTest 트랜잭션과 MemberService의 트랜잭션이 동일한 트랜잭션이기에 스프링은 동일한 EntitiyManager를 제공하므로, 동일한 영속성 컨텍스트에 접근하기때문에, 엔티티 동일성을 보장한다. (요부분은 궁금한 내용입니다!) 3. spring boot를이용하면 @PersistenceContext로 EntitiyManagerFactory로부터 EntitiyManager를 받아오는것을 지원하는데, spring data jpa를 이용하면 스프링 컨테이너에서 스프링 빈 DI하는것과 같이 생성자주입(여타 다른 주입도 상관없음,, 필드주입,, setter주입)을 통해서 EntitiyManager를 받아올수있다고 하셨는데, 그럼 EntitiyManager가 스프링빈과같이 스프링 컨테이너에 존재한다는 의미인가요??? 항상 잘듣고있습니다. 읽어주셔서 감사합니다.
저랑 비슷한 고민을 하시는분의 질문들을 봤는데 "내부적으로 값을 가지고 있기에 쿼리가 안나간다" 라는 답변을글 보았습니다 ! 1.여기서 내부적이라는게 그냥 순수 자바객체를 뜻 하시는걸까 요?(영속 컨텍스트는 clear로 깨끗해졌지만 자바 객체는 아직 남아있으니) 2. name값도 내부적으로 남아있다고 생각이 드는데 제가 좀 놓친부분이 있을까요?? ㅠㅠ 3. 이미 em.getReference에 파라미터로 id값을 넣었기 때문에 이미 알고있다고 jpa가 인식해서 쿼리를 안내보내는건가요 ??
`익명 사용자` 라는 것이 그냥 보기에는 접속이 가능한 것처럼 보였지만, 강의와 여러 QnA 를 다시 보다알게된 결론으로 정리를 해보았습니다. Spring Security 에서의 `익명사용자` 개념 정리 인증이 되기 전이나, 이후 의 사용자 모두 유효한 인증토큰을 갖고있지 못하면 `익명 사용자`이다 `익명 사용자`는 로그인이 가능한 경로를 통해 인증허가를 을 받게 될 경우, 일반 사용자로 등극하여, 로그인 접속 및 향후 접속유지가 가능하게된다. 인증을 받지 못한 사용자는 `익명 사용자`로 분류되어, `익명 사용자` 인증 토큰이(인증 객체) 익명 사용자 관리 명목으로 생성되지만, 로그인과 관련된 접근 권한은 없다(세션 생성이 되지않음) -> `redirect /login page` `익명 사용자` 전용으로 발급된 인증토큰을 통해, 향후 `익명 사용자` 접근 여부를 관리 할 수 있다 틀린 부분이 있다면 조언을 구합니다. 감사합니다.
안녕하세요 영한님 강의도 듣고, 책도 잘읽고 있습니다. 요즘엔 책을 주로 읽고 있네요 ㅎㅎ 다름이 아니라 제가 질문이 있습니다. 제가 jpa를 사용하는 개인 프로젝트를 진행중이고, 영한님 책을 보면서 많은 도움을 받고있습니다. 그런데 책에는 주로 join이 많아야 한번정도 있는 예제들이 많은데, 제가 사용하는 쿼리는 join을 4번씩이나 하고, 그렇게 해서 나온 결과 행들중 랜덤으로 하나의 row를 추출해야하는 형태라 order by random() limit 1 이런식의 조건을 주려했습니다. 다소 조인이 많이들어간 쿼리인데 spring data jpa 의 @query를 사용하려다보니 쿼리가 너무 길어서 뭔가 하드코딩하는 느낌도 들고, @query에서는 rand를 지원하지 않더군요... 이런경우에는 주로 querydsl을 사용하나요? 다른 질문을 보니 creteria 는 사용하지 않는게 좋다는 의견이있으셔서 질문드립니다. 아니면 단순히 jparepository를 구현한 repository 인터페이스를 이용해서도 해결이 가능할까요?ㅠㅠ
안녕하세요. DDD Start라는 책을 함께 읽으며 영한님의 강좌를 다시 한번 보고 있습니다. 그러던 도중 과연 어디까지 비즈니스 로직으로 보아야할까에 대한 의문점이 생겼습니다. 책에서는 도메인(엔티티) 쪽에 비즈니스 로직을 두고 서비스 레이어는 각 도메인의 함수를 호출하는 형태로 구현하여 서비스를 최대한 얇게 만들어야한다고 하더라구요. 그런데 이번 강의 2분 49초쯤을 보면 중복 회원을 검증하는 코드가 서비스 레이어에 위치해있습니다. 회원가입이라는 기능에서 중복 회원 검증이라는 규칙은 서비스에 있어 핵심 비즈니스 로직이라고 생각하는데요. 이 부분을 엔티티쪽에 두어 검증하지않고 서비스 레이어에 두셔서 혼란이 오더라구요. 질문을 요약하자면, 1. 중복 회원 검증 코드는 비즈니스 로직이라고 봐야할까요? 2. 맞다면 비즈니스 로직은 엔티티에 들어가야 하지 않나요? 3. 요구사항에는 중복 검증뿐만 아니라 수많은 검증 로직들이 존재할텐데, 이를 서비스에 작성해야할지 엔티티에 작성해야할지 어떠한 기준으로 판단해야할까요? 4. 도메인(엔티티)에서는 레포지토리를 호출하면 안된다고 알고 있습니다. 현업에서는 이를 명확하게 지키면서 코드를 작성하나요? 5. 만약 4번이 맞다면, 중복 회원 검증의 경우 실제 데이터베이스에 조회하는 쿼리를 날려야합니다. 이렇게 데이터베이스에 접근해야하는 로직의 경우 엔티티에 작성하면 안되는걸까요? (모든 질문은 DDD를 기반으로 질문드립니다!) 많은 예제들을 살펴보아도 서비스레이어에 작성할지 엔티티쪽에 작성할지 기준을 잡기가 정말 힘드네요.. 이 부분에 대해서 영한님의 의견을 듣고 싶습니다. 감사합니다 :)
안녕하세요 선생님 강의 잘 듣고 있습니다. Delivery에 Address가 있는데 이 값은 Delivery에 있는 Order를 참조하고 그 안에 있는 Member를 참조하면 가져올 수 있지 않나요 ? 참조가 너무 많이 일어나기 때문에 Address를 Delivery에 선언하는건가요 ??
- 학습 관련 질문을 남겨주세요. 상세히 작성하면 더 좋아요! - 먼저 유사한 질문이 있었는지 검색해보세요. - 서로 예의를 지키며 존중하는 문화를 만들어가요. - 잠깐! 인프런 서비스 운영 관련 문의는 1:1 문의하기를 이용해주세요. . 안녕하세요. 김영한 강사님. 김영한님 강의를 열심히 수강하는 학생입니다. . 다름이 아니라 제가 "페치조인 2 - 한계" 챕터의 13분 부터 19분까지 진행되는 강의 내용중 이해가 안되는 부분이 있어서 이렇게 질문을 하려합니다. . 분명 강의 내용에서는 컬렉션을 페치조인 한 후 페이징 API를 사용할 수 없다고 하였습니다. . 그리고 이를 극복하기 위하여 @BatchSize를 이용하는 방법이 소개되는데, 이 방법이 어떤 면에서 해결에 도움이 되는지 모르겠습니다. . 컬렉션을 페치조인 한 후 페이징 API를 사용할 수 없는 이유는 1대다 조인으로 뻥튀기된 데이터들을 페이징API로 DB에서 잘라올 경우 JPA가 잘려진 데이터만 받기 때문에 이를 기반으로 잘못된 정보를 내보낼 수 있기 때문이었습니다. . 그리고 @BatchSize는 LazyLoadi ng 된 데이터들을 사용할때마다 가져오지 않고 한꺼번에 가져오는 역할을 담당하여 Lazyloading의 성능을 개선하는 역할을 하고 있습니다. . 이것만 놓고 보면 @BatchSize가 컬렉션 페치조인의 페이징과 어느 면에서 관련있는지 모르겠습니다. 한꺼번에 가져오는 기능은 데이터가 잘려들어오는 것과 관련이 없어 보이거든요. 혹시 제가 잘못알고 있는걸까요? 답변 부탁드립니다.
안녕하세요! 강의에서 기존 테스트를 통합 테스트로 변경하면서 생성자 주입 코드가 필드 주입 코드로 변경되었는데요 @Autowired MemberService memberService ; @Autowired MemberRepository memberRepository ; 필드 주입으로 변경한 후 MemberRepository를 Autowired 받는 부분은 주석 처리를 해도 테스트 코드가 정상적으로 수행되더라고요 @Autowired MemberService memberService ; // @Autowired MemberRepository memberRepository; 생각을 해보니 MemberService를 Autowired할 수 있다는 건 MemberService 빈이 이미 생성되어 있다는 거고 MemberService 빈이 생성되려면 MemberService 생성자의 매개변수로 받을 MemberRepository가 필요하기 때문에 MemberRepository 빈도 이미 생성되어 있다는 거고 결국 MemberRepository 빈을 전달하면서 MemberService 빈을 생성했기 때문에 이후부터는 필드 주입이든 생성자 주입이든 MemberService를 Autowired하기 위해 MemberRepository가 함께 쓰이지 않아도 될 것 같더라고요 혹시 아니라면 MemberRepository를 주입받는 코드의 용도가 따로 있는 건가요?
강사님 항상 좋은 강의 감사합니다! 연관관계 편의 메소드에 내부에 set과 add , get이 각각 들어갈때가 다르길때 혹시 어떤 경우일때 set이고 get인지 알고 싶습니다. 제가 생각했을때는 1) member엔티티와 order 엔티티 간 setMember메소드에서 member는 다대일 중 '다'이므로 setMember 메서드를 만들어야 했던건가요? 2) 마찬가지로 그렇다면 order와 orderItem 사이에서 orderItem은 일대다 의 '일' 이므로 addOrderItem()메서드가 생성되었다 생각을 했는데 그렇게 따지니 setDelivery() 메서드가 이해가 가지 않습니다. 일대일의 관계로 '일'에 위치해 addDelivery()인가 싶기도 하였으나 그렇지 않더라고요 ㅠㅠ 3) setDelivery()메서드는 set으로 시작하는 setMember() 메서드와 같은 방식으로 작성하는 것인가 했는데 메서드 내부에서는 this . delivery = delivery ; // 배송지 설정 delivery.setOrder( this ) ; 이렇게 set메서드와 add메서드가 섞여있는 것 같은데 이해가 많이 부족한 것 같습니다.. 혹시 이에 관해서 답변해주실 수 있을까요?
안녕하세요. 저는 주로 postgresql 을 사용하는데 공간 데이터 관련 postgis 공간 함수나 postgres의 with recursive 같은 구문을 사용해야 할 일들이 있는데 이런것들도 querydsl 을 사용하면 쓸 수 있을까요? 아니면 이런 것들은 네이티브 쿼리나 jdbc 템플릿, 마이바티스 등등.. 어떤걸 사용하는게 좋을지 궁금합니다.
안녕하세요 선생님 지금까지 실행은 잘 되다가 크롬에서 http://localhost:8080 이 안되서 어제 application.properties 에 server.port = 8082 로 변경하여 잘나왔었는데 또 무언가를 잘 못건드렸는지 사이트에 연결할 수 없음 localhost 에서 연결을 거부했습니다. 다음 방법을 시도해 보세요. 연결 확인 프록시 및 방화벽 확인 ERR_CONNECTION_REFUSED 이렇게 나옵니다. 포트 번호를 다른것으로 바꿔도 위와 같이 나오는데 이유가 무엇인가요??