안녕하세요 선생님 질문이 생겨서 글 남깁니다.! 선생님이 생각하시는 가장 이상적인 테스트 코드 범위는 어디 까지인가요?? 예를들어 controller,service,repository가 있다고 가정하고 선생님 강의처럼 각각 레이어별로 테코를 짜고 service 쪽도 repo를 mock처리하여 단위테스트까지도 진행 하여야하나요? 제 질문을 정리하자면 controller,service,repository 각각 단위테스트 작성후 service + repo로 통합테스트 하는게 옳은 이상적인 범위인가 궁금합니다 감사합니다
[질문 템플릿] 1. 강의 내용과 관련된 질문인가요?네 2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? 네 3. 질문 잘하기 메뉴얼을 읽어보셨나요? 네 안녕하세요, 임베디드 타입에 대해 수강하던 중 별 것 아닐 수도 있는 것에 대해 제가 생각한 것이 맞나 확인 차 여쭤보고 싶어 질문드리게 되었습니다. 임베디드 타입 강의 중간부터 값타입이라는 말이 많이 나오는데, 임베디드 타입 = 값타입으로 이해를 하는게 맞는 것일까요 ?
[질문 템플릿] 1. 강의 내용과 관련된 질문인가요 네 2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? 네 3. 질문 잘하기 메뉴얼을 읽어보셨나요? 네 [질문 내용] 강의 내용대로 쿼리 결과보려고하는데 회원1,2 가져오고 회원3인 teamB를 영속성에 올리는 쿼리가 따로 안돌아요. 연속으로 회원1,2,3가져오는데 새 버전이라 그런건지 제가 설정을 잘못했는지 궁금합니다
강의를 들어본 후, 다른 질문들도 참고를 해보았는데요. 프록시 초기화(프록시객체의 초기화) : 프록시 객체의 target필드에 실제 엔티티 객체의 참조를 설정하는것. 1. <프록시 초기화 과정> em.getReference()를 하게되면, 프록시 객체가 영속성컨텍스트(1차캐시)에 저장된다. 프록시는 내부에 Member target;이라는 멤버변수(필드)를 가지고 있다. member.getName()을 호출한다. 프록시가 아직 초기화되지않은 상태이므로, JPA는 영속성 컨텍스트에 초기화 요청을 한다. 영속성컨텍스트가 db조회를 해서 실제 엔티티객체를 생성하고 프록시 객체 내부의 target필드에 실제 엔티티객체의 참조를 설정한다. 초기화된 필드를 통해 실제 객체의 메서드를 호출한다. --------------------------------------------------------------------- 2. em.getReference()를 하게되면, 프록시 객체가 영속성컨텍스트(1차캐시)에 저장된다. 초기화를 해도 실제 객체는 1차캐시에 저장되지않는다. 프록시 객체가 실제 객체의 참조를 가지고있기 때문에 프록시 객체를 통해 실제 객체를 사용할 수 있다. 즉 실제 객체가 1차캐시에 등록되는건 아니고 프록시 객체가 실제 객체의 참조를 가지고 있기 때문에 실제 객체가 1차 캐시에 등록되어 있는 것처럼 사용할 수 있다. ==> 프록시 객체만 영속성컨텍스트에 저장되고 실제 엔티티객체는 영속성컨텍스트에 저장되지않는다. --------------------------------------------------------------------- 3. JPA는 동일한 트랜잭션안에서 동일한 PK에 대해 처음에 em.getReference()를 사용하면 프록시 객체를 반환하고, em.find()를 사용해도 프록시 객체를 반환한다. 이때 프록시 객체가 영속성컨텍스트(1차캐시)에 저장된다. 이후 em.find()를 사용해도 이미 1차캐시에 프록시가 존재하므로 프록시가 반환된다. 반대의 경우 동일한 트랜잭션안에서 처음에 em.find()를 사용하면 실제 엔티티가 반환되고, em.getReference()를 사용해도 실제 엔티티를 반환한다. 이때 실제 엔티티가 영속성컨텍스트(1차캐시)에 저장된다. 이후 em.getReference()를 사용해도 이미 1차캐시에 실제 엔티티가 존재하므로 실제 엔티티가 반환된다. 위와 같이 이해하는게 맞을까요..?
링크 위 링크 속 질문에 대한 답변을 아래와 같이 이해하였습니다. em.remove(member)를 하는 순간에 member가 1차 캐시에서 제거되고 동시에 delete 쿼리가 쓰기 지연 SQL 저장소에 저장 commit()을 만나면 내부적으로 flush()를 호출하고 쓰기 지연 SQL 저장소에 있는 쿼리가 나간다고 이해했습니다. 그리고 아래와 같은 테스트를 했을 때 의문이 생겼습니다 Member member1 = em.find(Member.class, 101L); em.remove(member1); Member member2 = em.find(Member.class, 101L); System.out.print(member2); // null tx.commit(); 위 테스트의 결과는 처음 member1을 찾을 때 select 문 1번 remove()로 인한 delete 문 1번 이처럼 총 2번 발생했습니다 하지만 제 생각은 remove()를 하면서 1차 캐시에서 지웠기 때문에 두 번째 find() 시에는 쿼리를 날려야 되는거 아닌가요? 그리고 또 이해가 안되는 부분은 member2를 찍어보면 null 이 나옵니다. commit()을 하기 전, 즉 flush()를 통해 remove()에 의해 만들어진 쓰기 지연 SQL 저장소에 저장된 delete 문이 나가기 전인데 왜 null 이 찍히는 걸까요? 정리하자면 두번째 find()는 왜 안 날라가는지 member2는 왜 null 인지 별도로 궁금한 점 쓰기 지연 SQL 저장소에 있는 쿼리들은 들어온 순서대로 나가나요?
안녕하세요. 강의 내용 15분쯤에 프록시 객체의 초기화 부분에서 설명해주신 부분이 잘 이해가 되지않아서 찾아보고 아래와 같이 정리해보았는데요. 이렇게 이해하는게 맞을까요? 프록시 초기화(프록시객체의 초기화) : 프록시 객체의 target필드에 실제 엔티티 객체의 참조를 설정하는것. em.getReference()를 하게되면, 프록시 객체가 영속성컨텍스트(1차캐시)에 저장된다. 프록시는 내부에 Member target;이라는 멤버변수(필드)를 가지고 있다. member.getName()을 호출해서 초기화 요청을 한다. JPA는 영속성 컨텍스트(1차캐시)에 실제 엔티티객체가 있는지 확인한다. 4-1. 있으면, JPA는 프록시 객체 내부의 target필드에 1차캐시에 있는 실제 엔티티객체의 참조를 설정한다. 4-2 없으면, JPA는 db조회를 해서 실제 엔티티객체를 생성하고 프록시 객체 내부의 target필드에 실제 엔티티객체의 참조를 설정한다. 초기화된 필드를 통해 실제 객체의 메서드를 호출한다.
질문 시에는 위 내용은 삭제하고 다음 내용을 남겨주세요. ========================================= [질문 템플릿] 1. 강의 내용과 관련된 질문인가요? (예) 2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예) 3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예/) [질문 내용] 선생님 질문이 있습니다. 강의 22:00 쯤 변경 감지 듣다가 궁금증이 생겼습니다. 질문은 영속 컨텍스트에 넣지 않은 상태로 DB에서 바로 가져올 땐 커밋 시점 보다 먼저 쿼리가 발생하나요? package hellojpa; import jakarta.persistence.*; import java.util.List; public class JpaMain { public static void main(String[] args) { EntityManagerFactory emf = Persistence.createEntityManagerFactory("hello"); EntityManager em = emf.createEntityManager(); EntityTransaction tx = em.getTransaction(); tx.begin(); try { Member member = em.find(Member.class, 450L); member.setName("XXXX"); // em.persist(member); System.out.println("=================="); tx.commit(); } catch (Exception e) { tx.rollback(); } finally { em.close(); } emf.close(); } } 출력결과 Hibernate: select m1_ 0.id , m1_ 0.name from Member m1_0 where m1_ 0.id =? ================== Hibernate: /* update for hellojpa.Member */update Member set name=? where id=? 예상 출력 결과는 === select ... update ... 이렇게 나올 줄 알았는데요 왜 이렇게 나오지 않을까요?
강의수강중에 Pageable import 관련하여 아래와 같은 Pageable을 선택하니까 오류가 나오더라구요...type unmatch 형태 //import java.awt.print.Pageable; springboot를 사용할 때는 아래와 같은 org.springframework의 형태가 import 우선순위가 되는것이 맞는건가요? import org.springframework.data.domain.Pageable;
안녕하세요 validation 강의를 듣고 질문 드립니다. 강의 속에서 설명하신대로 하고 postman에서 실행을 하려고 보니 동작은 하는데 비밀번호 조건이 충족되지 않아도 defaultMessage가 뜨지않고 회원가입이 완료되었다는 창이 뜹니다ㅜㅜ @Valid 어노테이션 사용도 다 했는데 뭐가 문제인걸까요?
private List<Product> findProductsBy(List<String> productNumbers) { return productRepository.findAllByProductNumberIn(productNumbers); } 그냥 이렇게 바로 리턴 해도 되지 않나요??
학습하는 분들께 도움이 되고, 더 좋은 답변을 드릴 수 있도록 질문전에 다음을 꼭 확인해주세요. 1. 강의 내용과 관련된 질문을 남겨주세요. 2. 인프런의 질문 게시판과 자주 하는 질문(링크)을 먼저 확인해주세요. (자주 하는 질문 링크: https://bit.ly/3fX6ygx) 3. 질문 잘하기 메뉴얼(링크)을 먼저 읽어주세요. (질문 잘하기 메뉴얼 링크: https://bit.ly/2UfeqCG) 질문 시에는 위 내용은 삭제하고 다음 내용을 남겨주세요. ========================================= [질문 템플릿] 1. 강의 내용과 관련된 질문인가요? (예/아니오) 2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예/아니오) 3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예/아니오) [질문 내용] 여기에 질문 내용을 남겨주세요. IDENTITY 전략일 때, 모아서 INSERT하는 게 불가능하다라고 말씀하셨는데, 이게 PK가 없는 상황에서만 불가능하고 다른 상황(pk가 있을 때 insert 쿼리, select 쿼리 등등)에서는 원래처럼 모아서 커밋 직전에 쿼리가 날라가는건지, 아니면 정말로 IDENTITY 전략일 땐, 모든 JPA가 생성하는 쿼리가 커밋 직전이 아닌 그 때 그 때 나가는건가요?