묻고 답해요
138만명의 커뮤니티!! 함께 토론해봐요.
인프런 TOP Writers
-
해결됨실전! 스프링 부트와 JPA 활용1 - 웹 애플리케이션 개발
질문입니다.
학습하는 분들께 도움이 되고, 더 좋은 답변을 드릴 수 있도록 질문전에 다음을 꼭 확인해주세요.1. 강의 내용과 관련된 질문을 남겨주세요.2. 인프런의 질문 게시판과 자주 하는 질문(링크)을 먼저 확인해주세요.(자주 하는 질문 링크: https://bit.ly/3fX6ygx)3. 질문 잘하기 메뉴얼(링크)을 먼저 읽어주세요.(질문 잘하기 메뉴얼 링크: https://bit.ly/2UfeqCG)질문 시에는 위 내용은 삭제하고 다음 내용을 남겨주세요.=========================================[질문 템플릿]1. 강의 내용과 관련된 질문인가요? (예/아니오)2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예/아니오)3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예/아니오)[질문 내용]복습 중 궁금한 것들이 생겨서 질문 드립니다. 1. @Repository 어노테이션을 붙이면 이 클래스는 EntityManager 가 관리하는 클래스가 된다는 걸 의미하나요? 2. @Transactional(readOnly = true) 를 이용하면 영속성 컨텍스트에 관리를 받지 않게 된다고 하는데 이것이 어떤 이점이 있는지 궁금합니다. 3. MemberController 에서는 @Valid 를 사용했는데 ItemController 의 create 메서드에서는 왜 @Valid 를 사용하지 않았는지 궁금합니다.
-
미해결자바 ORM 표준 JPA 프로그래밍 - 기본편
페치조인 별칭
학습하는 분들께 도움이 되고, 더 좋은 답변을 드릴 수 있도록 질문전에 다음을 꼭 확인해주세요.1. 강의 내용과 관련된 질문을 남겨주세요.2. 인프런의 질문 게시판과 자주 하는 질문(링크)을 먼저 확인해주세요.(자주 하는 질문 링크: https://bit.ly/3fX6ygx)3. 질문 잘하기 메뉴얼(링크)을 먼저 읽어주세요.(질문 잘하기 메뉴얼 링크: https://bit.ly/2UfeqCG)질문 시에는 위 내용은 삭제하고 다음 내용을 남겨주세요.=========================================[질문 템플릿]1. 강의 내용과 관련된 질문인가요? (예/)2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예/)3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예/)[질문 내용]질문 1 ============================================별칭과 관련하여 영한님의 댓글을 찾아보던 도중 라는 글이 있습니다. 제가 이해한 바로는1:N 이던 N:1 이던 1:1 이던페치조인할때 별칭은 사용하지 않는것이 좋지만페치 조인시 별칭을 사용했을때와 별칭을 사용하지 않았을때와 의 데이터가 일치한다면(정합성) 사용 할수 있다 이렇게 이해를 했는데 맞나요 ? 질문 2 ============================================ 페치조인시 1:N 에서 페이징을 사용할수 없는 이유는페치조인의 메커니즘 자체가 1:N 이면 N 만큼 데이터를 다 가지고 있어야 하는데ex) @OneToMany(mappedBy = "team")private List<Member> members = new ArrayList<>();(Team 은 페치조인시 members 의 뻥튀기 된 데이터를 모두 가지고 있어야한다) 그런데 이때 페이징을 실행하면 뻥튀기된 데이터를 가지고 있을수가 없다.그래서 JPA는 메모리에 모든 정보를 끌어모아 저장 시킨후 메모리에서 페이징 처리를 실행 하기 때문에 메모리 부족 현상이 나타날수 있다 이렇게 이해를 했는데 맞나요 ? (질문1,2) ======================질문3페이징 처리를 위해N:1 을 1:N 으로 바꿔서 페치조인을 하면 되는데막상 이 쿼리를 디비에 실행해도 둘다 데이터가 각 3건씩 똑같이 나오는게 맞나요 ? (뻥튀기 가 일어나면 데이터가 더많아야 하는게 아닌가요 ? 1:n 조인이) 각각 1:N , N:1 페치조인 실행한 결과 [데이터 뻥튀기는 -> 데이터 베이스 쿼리는 동일하게 나오나, 자바 객체에서 뻥튀기 ->[중복] 현상이라고 생각하면 되는건가요 ??] 이 부분은 몆번을 봐도 햇갈리네요
-
미해결호돌맨의 요절복통 개발쇼 (SpringBoot, Vue.JS, AWS)
QueryDsl 추가 과정에서 질문이 있습니다..
안녕하세요 선생님. Querydsl 설정하는 부분에서 질문이 있습니다.호돌맨님 강의영상처럼 똑같이 보고 따라했는데 제꺼에선 Q클래스를 인식하지를 못 하더라구요.제가 기존에 영한님 강의에 익숙해져서 빌드 도구를 gradle이 아니라 인텔리제이로 해놨었거든요.그래서 혹시 몰라 gradle로 바꾸니 이제 QClass가 잘 생성이 되네요.혹시 이 부분은 어느 키워드로 검색을 해야할까요..?
-
미해결실전! Querydsl
프로퍼티 접근 방법과 setter
안녕하세요 궁금한 부분이 있어 질문 남깁니다 7:58~ 에서프로퍼티 접근은 setter 를 통해 값이 들어가므로@Data 애노테이션을 지우고 직접 getter, setter를 만들어주셨습니다. 저는 setter가 없으면 오류가 날 것이라 생각하여getter, setter를 생성하지 않고 테스트를 해보았는데 정상적으로 실행되더라고요. 오류가 나지 않는 게 맞는지, 그렇다면 이유가 무엇인지 궁금합니다 ㅠㅠ 아래는 실행한 코드입니다public class MemberDto { private String username; private int age; public MemberDto() { } }@Test public void findDtoBySetter() { List<MemberDto> result = queryFactory .select(Projections.bean(MemberDto.class, member.username, member.age)) .from(member) .fetch(); for (MemberDto memberDto : result) { System.out.println("memberDto = " + memberDto); } } +추가.......뒤늦게 MemberDto에 @ToString 을 달아 확인해보았습니다.오류는 나지 않았지만 안에 값은 없었네요 ㅎㅎㅎ.......
-
해결됨실전! 스프링 부트와 JPA 활용1 - 웹 애플리케이션 개발
기본키 자동 증가 (GeneratedValue)
안녕하세요, 기본 키 자동 증가에 관해서 궁금한 게 있어서 질문 드립니다.기본 키 자동 증가를 @GeneratedValue만 작성해주셨는데찾아보니 @SequenceGenerator 라는 어노테이션도 있더라고요, 이 어노테이션은 굳이 사용을 안 해줘도 되는 것 인가요?
-
미해결호돌맨의 요절복통 개발쇼 (SpringBoot, Vue.JS, AWS)
PostCreate 기본 생성자 문제 질문드립니다.
우선 수업 잘 듣고 있습니다 호돌맨님! 많이 배우고 있어요 ㅎㅎ제목에서와 같이 PostCreate 부분에서 기본 생성자에 관해 질문을 드립니다. // @Setter @Getter @NoArgsConstructor // TODO: 왜 이게 꼭 있어야 하는 것일까? public class PostCreateDto { @NotBlank(message = "타이틀을 입력해주세요.") private String title; @NotBlank(message = "내용을 입력해주세요.") private String content; @Builder public PostCreateDto(String title, String content) { this.title = title; this.content = content; } }우선 이건 제 코드입니다. 보시면 제 코드에는 @NoArgsConstructor 어노테이션이 있는데요. 이 부분이 없으면 제 PostControllerTest에서는 테스트 실패가 뜨더라구요. 에러 메시지는 다음과 같습니다. Caused by: com.fasterxml.jackson.databind.exc.InvalidDefinitionException: Cannot construct instance of com.blog.request.PostCreateDto (no Creators, like default constructor, exist): cannot deserialize from Object value (no delegate- or property-based Creator)에러메시지를 읽어보니 생성자가 없다는 문제 같아서 @NoArgsConstructor 어노테이션을 붙여보니 정상적으로 작동을 하더군요.이 부분이 궁금해서 찾아보니 RequestBody로 넘어오는 데이터를 맵핑할 때 Jackson의 ObjectMapper가 사용되는데 이게 RequestBody를 생성할 때, DTO가 Property기반이 아니거나 Delegate를 한 상태가 아니라면 기본 생성자로 생성한다 라고 나와있네요. (https://velog.io/@conatuseus/RequestBody%EC%97%90-%EC%99%9C-%EA%B8%B0%EB%B3%B8-%EC%83%9D%EC%84%B1%EC%9E%90%EB%8A%94-%ED%95%84%EC%9A%94%ED%95%98%EA%B3%A0-Setter%EB%8A%94-%ED%95%84%EC%9A%94-%EC%97%86%EC%9D%84%EA%B9%8C-3-idnrafiw)그리고 바인딩할 때 Setter가 없이도 자바 리플렉션을 통해서 DTO에 값이 들어간다고 하는 것도 이번에 알게 됐네요. 그래서 Setter를 지우고 Getter랑 @NoArgsConstructor 어노테이션만 붙이고 테스트를 돌려보니 통과가 잘 됩니다. 그런데 호돌맨님이 올려주신 코드를 보니 PostCreate 부분에 기본생성자가 없더라구요. 그런데도 테스트통과가 잘 되는 것을 보니까 신기하네요. 어떻게 그게 가능한 것인지 설명해주실 수 있나요?
-
해결됨실전! 스프링 데이터 JPA
Auditing 기능 질문
안녕하세요, Auditing 기능에 대해서 궁금한 게 생겨 질문 드립니다.Auditing 이라는 기능으로 작성일, 수정일, 작성자, 수정자를 기록할 수 있다고 해주셨는데 삭제일, 삭제자를 기록하는 기능은 Auditing에서 제공 안 해주는 건가요?구글링 해봐도 그런 기능은 없는 것 같아서요.(다른 기술을 사용해야 하는 건가요?)
-
미해결자바 ORM 표준 JPA 프로그래밍 - 기본편
strategy = GenerationType.IDENTITY 테이블은 생성이 되지만 필드가 DB에 데이터가 없습니다
학습하는 분들께 도움이 되고, 더 좋은 답변을 드릴 수 있도록 질문전에 다음을 꼭 확인해주세요.1. 강의 내용과 관련된 질문을 남겨주세요.2. 인프런의 질문 게시판과 자주 하는 질문(링크)을 먼저 확인해주세요.(자주 하는 질문 링크: https://bit.ly/3fX6ygx)3. 질문 잘하기 메뉴얼(링크)을 먼저 읽어주세요.(질문 잘하기 메뉴얼 링크: https://bit.ly/2UfeqCG)질문 시에는 위 내용은 삭제하고 다음 내용을 남겨주세요.=========================================[질문 템플릿]1. 강의 내용과 관련된 질문인가요? (예/아니오)2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예/아니오)3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예/아니오)[질문 내용]여기에 질문 내용을 남겨주세요.
-
미해결자바 ORM 표준 JPA 프로그래밍 - 기본편
제가 이해한게 맞는지 확인 부탁드릴게요
영속성 컨텍스트는 트랜잭션이 시작 후 종료되면 영속성 컨텍스트는 삭제된다.플러시는 영속성 컨텍스트를 비우지 않는다. 8분 17초 에서 약간 헷갈리는게 있다면 트랜잭션 작업이 모두 끝나면 영속성 컨텍스트는 삭제가 되고플러시의 역할은 쓰기 지연 SQL 저장소에 저장된 SQL 을 DB로 전달해 실행하게끔 해주는 역할인거지 영속성 컨텍스트를 지우는 역할은 아닌거죠?
-
미해결Spring Cloud로 개발하는 마이크로서비스 애플리케이션(MSA)
UserDto 의 pwd 값 관련
안녕하세요. 좋은강의 감사합니다.다름이 아니라 강의에서 설명하실때는getUserDetailsByEmail 메소드에서 UserEntity 를 UserDto로 맵핑할때클라이언트가 입력한 password를 Spring Security 가 UserDto의 pwd 파라미터에 암호화하여 넣어준다는 식으로 말씀하신거 같습니다.@Override public UserDto getUserDetailsByEmail(String userName) { UserEntity userEntity = userRepository.findByEmail(userName); if(userEntity == null) throw new UsernameNotFoundException(userName); UserDto userDto = new ModelMapper().map(userEntity,UserDto.class); return userDto; 그게 아니라 단지, ModelMapper 에 STRICT 설정을 해주지 않아서 UserDto의 pwd와 encrytedpwd 값이 모두 UserEntity의 password 값으로 들어간게 아닌가 해서 질문드립니다.
-
미해결자바 ORM 표준 JPA 프로그래밍 - 기본편
부모와 자식 엔티티 간의 id 속성 상속에 대해 문의 드립니다.
예제를 구현하다가 부모 엔티티와 자식 엔티티 간의 id 속성에 대해 궁금증이 생겨 문의 드립니다. 보통 엔티티 생성 시 @Id가 있는 필드를 정의하지 않으면 인텔리제이에서 경고문구를 띄워줍니다. 저도 @Entity 사용 시 @Id 컬럼 지정을 반드시 해야 한다고 배웠습니다. 그런데 상속관계 매핑 예제를 구현하다가부모인 Item 엔티티 클래스와 자식인 Album 엔티티 클래스에서 ,자식 Album 엔티티 클래스에 오히려 @Id를 지정하니 에러가 발생했습니다.==> [ org.hibernate.mapping.JoinedSubclass cannot be cast to org.hibernate.mapping.RootClass ] 처음엔 extends를 했으니, @Id 필드가 자식에게 상속되는 건가?.. 싶었는데private 속성은 상속되지 않잖아요?.. 혹시 자식 엔티티에 @id를 설정하면 안돼는 이유를 알 수 있을까요?? [ 부모 Item entity class ]@Entity @Inheritance(strategy = InheritanceType.SINGLE_TABLE) public class Item { public Item() { } @javax.persistence.Id @GeneratedValue @Column(name = "ITEM_ID") private Long Id; private String name; private int price; [ 자식 Album entity class ]@Entity public class Album extends Item{ public Album() { } /* @javax.persistence.Id @GeneratedValue @Column(name = "ITEM_ID") private Long id;*/ // ---- 추가시 에러 발생 private String director; private String actor;
-
미해결실전! 스프링 부트와 JPA 활용1 - 웹 애플리케이션 개발
안녕하세요
학습하는 분들께 도움이 되고, 더 좋은 답변을 드릴 수 있도록 질문전에 다음을 꼭 확인해주세요.1. 강의 내용과 관련된 질문을 남겨주세요.2. 인프런의 질문 게시판과 자주 하는 질문(링크)을 먼저 확인해주세요.(자주 하는 질문 링크: https://bit.ly/3fX6ygx)3. 질문 잘하기 메뉴얼(링크)을 먼저 읽어주세요.(질문 잘하기 메뉴얼 링크: https://bit.ly/2UfeqCG)질문 시에는 위 내용은 삭제하고 다음 내용을 남겨주세요.=========================================[질문 템플릿]1. 강의 내용과 관련된 질문인가요? (예/아니오)2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예/아니오)3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예/아니오)[질문 내용] h2 DB는 서버를 실행할 때 마다 초기화가 되는데 그 이유는 무엇인가요?
-
해결됨
서비스 테스트 코드 계층에 @Transactional
@Transactional프로젝트를 하던 도중에 서비스 계층 테스트를 진행을 할 때에 @Transactional을 안넣고 진행했더니 데이터가 제대로 적용이 안되는 에러가 생겼습니다. 근데 다른 서비스를 테스트 할 때에는 안넣고 진행을 했는데 정상적으로 되는 경우도 있었습니다.물론 롤백에 관한 처리를 @AfterEach로 각 레포지토리를 비우고 진행했습니다.여기서 궁금한 점이 하나 생기는데 왜.. @Transactional을 테스트 코드에 넣지 않으면 제가 생각한 데이터가 나오지 않는 걸까요?.. Lazy Loding 이거 때문이라고는 하는데 잘 모르겠습니다.
-
미해결실전! 스프링 부트와 JPA 활용2 - API 개발과 성능 최적화
처음에 무한 Loop 을 돌게 되는 이유
안녕하세요~ 강의 중 처음에 order 들을 조회하는 api 가 무한 루프를 도는 이유가 궁금해서 질문을 올리게 되었습니다 (6분 30초 ~ 7분 부분)우선, Order > Member > Order 조회 의 순으로 일어나기 때문에 무한 루프가 발생한다고 설명해주셨습니다.이 때, Order 는 member 가 Lazy 설정이 되어 있고, Member 에도 List<Order> 를 가져오는 것이 Lazy 로 설정이 되어 있습니다 (@OneToMany 이기 때문) .[모든 order 를 조회하라] 라는 로직에 member 를 join 해서 가져오기 대문에, Order 가 Member 를 조회해서 가져오는 부분은 이해를 하였습니다. 쿼리도 다음과 같이 나가더라구요! 2023-01-15 18:08:52.603 DEBUG 74756 --- [nio-8080-exec-1] org.hibernate.SQL : select order0_.order_id as order_id1_6_, order0_.delivery_id as delivery4_6_, order0_.member_id as member_i5_6_, order0_.order_date as order_da2_6_, order0_.status as status3_6_ from orders order0_ inner join member member1_ on ( order0_.member_id=member1_.member_id ) 2023-01-15 18:08:52.713 DEBUG 74756 --- [nio-8080-exec-1] org.hibernate.SQL : select member0_.member_id as member_i1_4_0_, member0_.city as city2_4_0_, member0_.street as street3_4_0_, member0_.name as name4_4_0_ from member member0_ where member0_.member_id=? 2023-01-15 18:08:52.722 DEBUG 74756 --- [nio-8080-exec-1] org.hibernate.SQL : select orders0_.member_id as member_i5_6_0_, orders0_.order_id as order_id1_6_0_, orders0_.order_id as order_id1_6_1_, orders0_.delivery_id as delivery4_6_1_, orders0_.member_id as member_i5_6_1_, orders0_.order_date as order_da2_6_1_, orders0_.status as status3_6_1_ from orders orders0_ where orders0_.member_id=?첫번째 쿼리로 join 을 하는데, <이후 호출>에 의하여 두, 세번째 쿼리가 나가는 것 같습니다.이 때, 각각의 멤버의 정보를 불러오기 위하여 member 쿼리가 나가는 것은 이해가 되는데, orderItem 이 LAZY 임에도 쿼리가 또 나가는 이유가 궁금합니다. response 가 나가는 과정에서 Json 형성을 위해 ObjectMapper 가 getMember, getOrderItem 등을 수행하는 것으로 알고 있는데, 이 때 불러오기 때문일까요?? 2.ObjectMapper 가 무시할 수 있도록 다음과 같이 변경후 실행시켜 보았습니다. @JsonIgnore @OneToMany(mappedBy = "member") private List<Order> orders = new ArrayList<>(); 이렇게 될 시엔 다음과 같이 Serializable 관련 에러가 발생하는 것 같았습니다. 그랬더니 두번재 쿼리까지만 나가긴 하는데, 다음과 같은 에러가 발생합니다.com.fasterxml.jackson.databind.exc.InvalidDefinitionException: No serializer found for class org.hibernate.proxy.pojo.bytebuddy.ByteBuddyInterceptor and no properties discovered to create BeanSerializer (to avoid exception, disable SerializationFeature.FAIL_ON_EMPTY_BEANS) (through reference chain: java.util.ArrayList[0]->com.example.actualjpa.domain.Order["member"]->com.example.actualjpa.domain.Member$HibernateProxy$jMkxupIu["hibernateLazyInitializer"])검색을 해보니 프록시 객체를 Serialize 하려고 했다는 에러가 발생하는 것 같은데, orders 에 프록시 값들이 들어있는게 맞을까요? 반대인 경우에는 DB 에 FK값이 있기 때문에 id 값만을 가지고 Proxy 객체를 형성한다는 점을 완전히 이해를 했었는데, 이와 같은 경우에는 각 ID 값이 DB에 없기 때문에, Member만 조회시 orders 내의 Order 들에 대한 프록시도 없고 아예 아무 정보도 없겠구나 라고 이해를 했었습니다.즉, 레이지일 경우 Member만 조회시 orders 에 대한 정보는 Member 객체에 없다 라고 이해를 했었습니다. @JsonIgnore를 해서 조회같은걸 할 수 없도록 했음에도, 위와 같은 에러가 발생하는 이유가 어떤건지 알 수 있을까요?? =========================위 질문에 대한 수정사항:제가 질문한 바로 뒷내용이 JsonIgnore 설정해주시고 같은 에러에 대해서 설명해주시는 부분 확인했습니다 ㅠㅠ 프록시 객체 때문에 발생하는 에러가 맞네요.그래도 같은 질문을 드리고 싶은데, 1:N 관계에서 Proxy 객체에 대해서 조금 이해가 안되었습니다(JPA 강의 완강했습니다). Apple 과 Tree 라는 N:1 관계에서 살펴보면 (양방향 모두LAZY 설정시) , Apple Entity 내의 private Tree tree가 있을 것이고, APPLE DB에는 외래키값으로 tree_id 가 들어가있을 것이기 때문에 그 값을 토대로 프록시 객체를 형성해 놓는다는 사실은 잘 이해하였습니다.하지만 그 반대일 경우 에 대해서 이해를 못한 것 같습니다 (JPA 강의에서도 반대에 대한 프록시 구성 설명은 없었던 것 같습니다 ㅠ). 반대의 경우 Tree DB 안에는 Apple 을 외래키값으로 가지고 있지 않은데, 어떻게 프록시 객체를 형성해 놓는 걸까요?? (프록시 객체를 형성해 놓기 때문에 위 2번과 같은 상황이 발생한 것으로 보입니다). 다음과 같은 예제를 설정해보았습니다.@Test @DisplayName("1:N에서 1이 N List를 조회시 :: LAZY LOADING 의 타입은 Proxy") void test2() { Tree findTree = em.find(Tree.class, tree.getId()); System.out.println("findTree.getApples().get(0).getClass() = " + findTree.getApples().get(0).getClass()); }이 때, em.find 만 해서 tree 를 조회하였을 경우 쿼리가 Tree 만을 조회하도록 나가는 것은 확인했습니다. 하지만, 그 아래 get(0) 를 수행하는 순간 "Apple 테이블에서 Tree_ID={tree_id} 인 값을 찾아와라" 라고 쿼리 문이 나가는 것을 확인했습니다. (getClass 를 통해 프록시가 맞는지 확인하려 했으나, get() 을 하는 순간 select 가 나가서 확인하지 못했습니다)즉,Apple 에서 Tree 프록시를 형성할 때는 Apple DB에 있는 외래키를 통해 Tree Proxy 에 PK 값을 넣어준 상태로 프록시를 형성하였는데, Tree 에서 Apple 들의 프록시를 형성할 때는 외래키가 없으므로, 그냥 자신의 PK 값을 통해 Apple 의 외래키 값을 넣어준 상태로 프록시를 형성해 둔다(??).이렇게 정리되는게 맞는 걸까요?질문이 너무 기네요.... 계속 붙이다 보니 .... 죄송합니다. 2번 질문은 그냥 아래 수정사항 이후 질문이라고 봐주시면 될 것 같습니다.
-
미해결생산성을 향상시키는 스프링부트 기반의 API 템플릿 프로젝트 구현
HttpServeletRequest 를 못가져오는 이슈
안녕하세요.강의중 AuditorAawareImpl.java 에서아래와 같이 의존성 주입하니@Autowiredprivate HttpServeltRequest httpServletRequest;-->"Autowired members must be defined in valid Spring bean.. " 이라고 에러가 납니다.Spring boot 2.7.7 버전인데요..어떻게 해야할지 문의드립니다..
-
미해결실전! 스프링 부트와 JPA 활용2 - API 개발과 성능 최적화
스프링 부트 3.0 findAll() 쿼리
안녕하세요!!강의 너무 잘 보고 있는 수강생입니다! 스프링 부트 3.0.1 버전으로 프로젝트를 생성해 강의를 듣다가 단순 전체 조회 쿼리(/api/v2/orders)인 findAll()에서 쿼리가 강의와 다르게 나와 궁금증이 생겨 질문 드립니다.제가 이해하기로는 /api/v2/orders를 호출하면 다음과 같은 순서로 데이터를 가져온다고 생각했습니다.orders 조회하는 쿼리 호출OrderDto 를 만드는 과정에서 getMember()와 getDelivery() 를 호출할 때 Member와 Delivery를 가져오는 쿼리 호출getOrderItems() 를 통해 orderItems 조회하는 쿼리 호출OrderItemDto 를 만드는 과정에서 getItem()을 호출할 때 각각의 Item을 가져오는 쿼리 호출그래서 강의처럼 데이터를 초기화 한다면 총 11번의 쿼리가 발생해야 한다고 생각했고 강의에서도 11번의 쿼리가 생겼습니다.하지만 제 코드에서는 getDelivery() 를 호출하는 과정에서 이상하게 Delivery를 호출한 후, deliveryId 를 조건절로 Order를 조회하는 쿼리가 한 번 더 생겨 아래 로그처럼 총 13번의 쿼리가 발생했습니다. 2023-01-14T18:10:31.860+09:00 DEBUG 6590 --- [nio-8070-exec-2] org.hibernate.SQL : select o1_0.order_id, o1_0.delivery_id, o1_0.member_id, o1_0.order_date, o1_0.status from orders o1_0 2023-01-14T18:10:31.890+09:00 DEBUG 6590 --- [nio-8070-exec-2] org.hibernate.SQL : select m1_0.member_id, m1_0.city, m1_0.street, m1_0.zipcode, m1_0.name from member m1_0 where m1_0.member_id=? 2023-01-14T18:10:31.890+09:00 TRACE 6590 --- [nio-8070-exec-2] org.hibernate.orm.jdbc.bind : binding parameter [1] as [BIGINT] - [1] 2023-01-14T18:10:31.895+09:00 DEBUG 6590 --- [nio-8070-exec-2] org.hibernate.SQL : select d1_0.delivery_id, d1_0.city, d1_0.street, d1_0.zipcode, d1_0.status from delivery d1_0 where d1_0.delivery_id=? 2023-01-14T18:10:31.895+09:00 TRACE 6590 --- [nio-8070-exec-2] org.hibernate.orm.jdbc.bind : binding parameter [1] as [BIGINT] - [1] 2023-01-14T18:10:31.899+09:00 DEBUG 6590 --- [nio-8070-exec-2] org.hibernate.SQL : select o1_0.order_id, o1_0.delivery_id, o1_0.member_id, o1_0.order_date, o1_0.status from orders o1_0 where o1_0.delivery_id=? 2023-01-14T18:10:31.900+09:00 TRACE 6590 --- [nio-8070-exec-2] org.hibernate.orm.jdbc.bind : binding parameter [1] as [BIGINT] - [1] 2023-01-14T18:10:31.910+09:00 DEBUG 6590 --- [nio-8070-exec-2] org.hibernate.SQL : select o1_0.order_id, o1_0.order_item_id, o1_0.count, o1_0.item_id, o1_0.order_price from order_item o1_0 where o1_0.order_id=? 2023-01-14T18:10:31.910+09:00 TRACE 6590 --- [nio-8070-exec-2] org.hibernate.orm.jdbc.bind : binding parameter [1] as [BIGINT] - [1] 2023-01-14T18:10:31.914+09:00 DEBUG 6590 --- [nio-8070-exec-2] org.hibernate.SQL : select i1_0.item_id, i1_0.dtype, i1_0.name, i1_0.price, i1_0.stock_quantity, i1_0.author, i1_0.isbn from item i1_0 where i1_0.item_id=? 2023-01-14T18:10:31.915+09:00 TRACE 6590 --- [nio-8070-exec-2] org.hibernate.orm.jdbc.bind : binding parameter [1] as [BIGINT] - [1] 2023-01-14T18:10:31.916+09:00 DEBUG 6590 --- [nio-8070-exec-2] org.hibernate.SQL : select i1_0.item_id, i1_0.dtype, i1_0.name, i1_0.price, i1_0.stock_quantity, i1_0.author, i1_0.isbn from item i1_0 where i1_0.item_id=? 2023-01-14T18:10:31.917+09:00 TRACE 6590 --- [nio-8070-exec-2] org.hibernate.orm.jdbc.bind : binding parameter [1] as [BIGINT] - [2] ============================================== 2023-01-14T18:10:31.919+09:00 DEBUG 6590 --- [nio-8070-exec-2] org.hibernate.SQL : select m1_0.member_id, m1_0.city, m1_0.street, m1_0.zipcode, m1_0.name from member m1_0 where m1_0.member_id=? 2023-01-14T18:10:31.919+09:00 TRACE 6590 --- [nio-8070-exec-2] org.hibernate.orm.jdbc.bind : binding parameter [1] as [BIGINT] - [2] 2023-01-14T18:10:31.921+09:00 DEBUG 6590 --- [nio-8070-exec-2] org.hibernate.SQL : select d1_0.delivery_id, d1_0.city, d1_0.street, d1_0.zipcode, d1_0.status from delivery d1_0 where d1_0.delivery_id=? 2023-01-14T18:10:31.921+09:00 TRACE 6590 --- [nio-8070-exec-2] org.hibernate.orm.jdbc.bind : binding parameter [1] as [BIGINT] - [2] 2023-01-14T18:10:31.922+09:00 DEBUG 6590 --- [nio-8070-exec-2] org.hibernate.SQL : select o1_0.order_id, o1_0.delivery_id, o1_0.member_id, o1_0.order_date, o1_0.status from orders o1_0 where o1_0.delivery_id=? 2023-01-14T18:10:31.923+09:00 TRACE 6590 --- [nio-8070-exec-2] org.hibernate.orm.jdbc.bind : binding parameter [1] as [BIGINT] - [2] 2023-01-14T18:10:31.925+09:00 DEBUG 6590 --- [nio-8070-exec-2] org.hibernate.SQL : select o1_0.order_id, o1_0.order_item_id, o1_0.count, o1_0.item_id, o1_0.order_price from order_item o1_0 where o1_0.order_id=? 2023-01-14T18:10:31.926+09:00 TRACE 6590 --- [nio-8070-exec-2] org.hibernate.orm.jdbc.bind : binding parameter [1] as [BIGINT] - [2] 2023-01-14T18:10:31.927+09:00 DEBUG 6590 --- [nio-8070-exec-2] org.hibernate.SQL : select i1_0.item_id, i1_0.dtype, i1_0.name, i1_0.price, i1_0.stock_quantity, i1_0.author, i1_0.isbn from item i1_0 where i1_0.item_id=? 2023-01-14T18:10:31.927+09:00 TRACE 6590 --- [nio-8070-exec-2] org.hibernate.orm.jdbc.bind : binding parameter [1] as [BIGINT] - [3] 2023-01-14T18:10:31.928+09:00 DEBUG 6590 --- [nio-8070-exec-2] org.hibernate.SQL : select i1_0.item_id, i1_0.dtype, i1_0.name, i1_0.price, i1_0.stock_quantity, i1_0.author, i1_0.isbn from item i1_0 where i1_0.item_id=? 2023-01-14T18:10:31.928+09:00 TRACE 6590 --- [nio-8070-exec-2] org.hibernate.orm.jdbc.bind : binding parameter [1] as [BIGINT] - [4] ============================================== 혹시나 제가 코드를 잘못 작성했을까봐 강의 자료로 올라온 소스코드에서 default_batch_fetch_size 만 주석 처리하고 스프링 부트 3.0 환경에서 돌려봤는데 같은 결과가 나왔고, JpaRepository 를 통한 findAll 로 두 버전에서 모두 테스트를 해봤는데 같은 결과가 발생했습니다. 그래서 Delivery에 @OneToOne으로 걸려있는 order가 문제라 생각해 이 부분을 지우고 실행했더니 해당 쿼리가 사라졌습니다. 하지만 @OneToOne의 패치 전략을 Lazy로 하고 따로 Order를 조회하지 않았고, 맨 처음 orders를 조회하는 쿼리를 실행하는 과정에서 영속성 컨텍스트에 orders가 저장 되기도 했기 때문에 해당 쿼리가 생기면 안된다고 생각을 했는데 혹시 제가 잘못 이해하고 있는걸까요..? 스프링 부트 3.0으로 올라가는 과정에서 hibernate의 버전도 6으로 올라가 뭔가 변경이 생긴것인지, 아니면 제가 어떤 실수를 하고 있는건지 궁금해서 질문 드립니다..!
-
미해결실전! Querydsl
count query 질문입니다
[질문 내용]아래처럼 List<MemberTeamDto> 를 쿼리해올때, 최적화를 위해 count query 를 따로 작성하셨는데, 왜 result.size() 로 바로 total count 값을 가져오면 안되는건지 궁금합니다! 이유가 무엇인가요?List<MemberTeamDto> result = queryFactory .select(new QMemberTeamDto( member.id.as("memberId"), member.username, member.age, team.id.as("teamId"), team.name.as("teamName"))) .from(member) .leftJoin(member.team, team) .where( usernameEq(condition.getUsername()), teamNameEq(condition.getTeamName()), ageGoe(condition.getAgeGoe()), ageLoe(condition.getAgeLoe()) ) .offset(pageable.getOffset()) .limit(pageable.getPageSize()) .fetch();
-
미해결실전! Querydsl
em.flush(),clear() 대신 @Modifying 어노테이션을 붙여도 되나요?
1. 강의 내용과 관련된 질문인가요? (예/아니오)2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예/아니오)3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예/아니오)[질문 내용]@Modifying 을 어노테이션으로 단다면, em.flush(),clear() 코드없이 동일한 동작을 수행하게 되나요?스프링 데이터 JPA에서는 Repository위에 달았는데요. 뒷 강의에서 Spring data JPA와 QueryDSL을 병행해서 사용하기 위해 custom Repository를 만든다고 배웠습니다. 이 custom Repository의 함수에 @Modifying을 달아도 동일하게 동작하는지 궁금합니다. 정리하자면 QueryDSL에서도 @Modifying이 적용되는지 궁금합니다.
-
미해결실전! 스프링 부트와 JPA 활용1 - 웹 애플리케이션 개발
item
학습하는 분들께 도움이 되고, 더 좋은 답변을 드릴 수 있도록 질문전에 다음을 꼭 확인해주세요.1. 강의 내용과 관련된 질문을 남겨주세요.2. 인프런의 질문 게시판과 자주 하는 질문(링크)을 먼저 확인해주세요.(자주 하는 질문 링크: https://bit.ly/3fX6ygx)3. 질문 잘하기 메뉴얼(링크)을 먼저 읽어주세요.(질문 잘하기 메뉴얼 링크: https://bit.ly/2UfeqCG)질문 시에는 위 내용은 삭제하고 다음 내용을 남겨주세요.=========================================[질문 템플릿]1. 강의 내용과 관련된 질문인가요? (예/아니오)2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예/아니오)3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예/아니오)[질문 내용]item 을 추상 클래스로 만든 이유가 뭘까요?
-
미해결자바 ORM 표준 JPA 프로그래밍 - 기본편
값 타입 컬렉션 대안
값 타입 컬렉션 대안으로 entity에 감싼다고 했는데요예를 들어 @Embedable인 Address를 그냥 처음부터@Entity로 승격시켜버리면 되는데 굳이 왜 감싸나요?