묻고 답해요
148만명의 커뮤니티!! 함께 토론해봐요.
인프런 TOP Writers
-
미해결실전! 스프링 부트와 JPA 활용1 - 웹 애플리케이션 개발
테스트 코드 autowired 질문입니다
안녕하세요. Test 코드에서 public class MemberRepositoryTest { @Autowired MemberRepository memberRepository; 이렇게 돼있던데요. 여기서 @Autowired로 주입을 받아야 하는 이유가 무엇인가요? 그냥 MemberRepository memberRepository = new MemberRepository(); 로 해도 될거같아서 해봤는데 에러가 나더라고요... Member 클래스는 그냥 Member member = new Member(); 이 형태로 쓸 수 있는데, MemberRepository 클래스는 어차피 예제 상황이라 싱글톤으로 안써도 되는 상황인데도 왜 굳이 의존성 주입으로만 해야하는건지 궁금합니다.
-
해결됨자바 ORM 표준 JPA 프로그래밍 - 기본편
안녕하세요 유니크 제약조건에 대해 궁금한 점이 생겨서 질문드립니다.
안녕하세요 강의를 듣고 복습하다가 유니크 제약조건에 대해서 궁금한 점이 생겨서 이렇게 질문을 드립니다. 책에서는 @Table(name = "Member", uniqueConstraints = @{UninqueConstraint ~~}) 이런식으로 적혀있는데 그러면 유니크 제약조건을 Member라는 테이블 에 있는 모든 colum에 거는건가요? 그리고 인터넷에서 찾아보니 @Column(unique = true)이렇게도 사용하던것 같던데 이렇게 사용하면 해당 @Column에만 유니크 제약조건을 거는 것이 맞나요?
-
미해결
ZonedDateTime 질문
시작날짜 ~ 종료날짜 Sdate , Edate를 DB상에서는 TIMESTAMP 타입 엔티티에는 ZonedDateTime으로 정의해뒀는데요 시작날짜를 기준으로 검색하는 쿼리를 작성하려고 하는데 ZonedDateTime.of 로 디폴트값을 지정한뒤 넘겨줬는데 타입이 안맞는다고 나오더라고요 그래서 parse를 사용하여 넘겨보았지만 이번에는 Unable to obtain ZoneId from TemporalAccessor: {},ISO resolved to 2020-01-18 of type java.time.format.Parsed 라는 에러가 뜨며 마찬가지로 정상적으로 넘어가지 않는데요.. ZonedDateTime으로 정의된 필드를 사용하여 원하는 날짜값을 매개변수로 넘겨 그 날짜에 해당하는 list를 출력하고 싶은데 어떻게 해야 할까요..
-
해결됨실전! 스프링 부트와 JPA 활용1 - 웹 애플리케이션 개발
레포지토리 바로 조회 시 트랜잭션 동작 방식에 대한 질문
강의명: 실전! 스프링 부트와 JPA 활용 1 해당 강의: 주문 목록 검색, 취소 안녕하세요 초보개발자 명아주입니다. 이번 강의를 들으면서 궁금증이 있어서 질문드립니다! orderList를 조회하는 로직을 orderService에서 orderRepository로 변경하는 방식을 선호하신다고 해서 저도 시도해봤습니다. 사실 이걸 시도하면서 JPA는 트랜잭션 안에서 처리가 되야 되기 때문에 레포지토리를 바로 타면 어떤 트랜잭션 처리를 하지 않았기 떄문에 에러가 나길 기대했습니다. 그런데 실제 결과는 정상 동작이었습니다. 조회 동작이니 트랜잭션에 덜 민감할 것이라고 생각은 드는데 그렇다하더라도 JPA는 무조건 트랜잭션 안에서 동작하는 것으로 알고 있는데 어떻게 이것이 동작하는지 궁금하더라구요. 일단, 이렇게 가져온 값을 뭔가 컨트롤러에서 변경해도 준영속 상태기 때문에 반영은 안될 것 같지만, 가져오는 것 자체가 트랜잭션을 안탔는데 왜 가능한지? 알고 싶습니다! 감사합니다. 명아주 드림
-
미해결실전! 스프링 부트와 JPA 활용1 - 웹 애플리케이션 개발
연관관계 편의 메서드 사용 목적 질문입니다.
[질문 템플릿]1. 강의 내용과 관련된 질문인가요? (예)2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (아니오)3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예)[질문 내용] 안녕하세요. 강의 정말 너무 잘 듣고 있습니다! ㅠㅠ JPA 무지한이던 제게 정말 큰 도움이 됐습니다. 강의를 다 듣고 복습중인데, 연관관계 편의 메서드 관련해서 궁금한 게 있어서 질문드립니다. public void setMember(Member member){ this.member = member; member.getOrders( ).add(this); } 를 통해 Order 엔티티에 member 정보를 넣어줌과 동시에 Member 엔티티에 order 정보를 넣어주는데요, 두 엔티티 모두에 값을 셋팅해주기 위함인 건 알겠는데, 실제로 어떤 상황에서 쓰이는지 잘 모르겠습니다. 위와 같이 연관관계 편의 메서드를 통해 Member의 order에 값을 넣어주면, service 등에서 order.setMember(member); 를 해주었을 때, 별도의 Member 객체를 생성해서 setOrders()를 해주지 않아도, member.getOrders(); 를 통해 해당 멤버에 저장된 order 정보들을 가져올 수 있다는 것까지는 알겠는데, 실제로 이게 어떤 상황에서 쓰이는 건지 잘 모르겠습니다. DB의 member 테이블에서는 order 관련 정보를 안갖고 있는데(그래서 변경감지로 Member 테이블을 업데이트 해주는 것도 아닐텐데), Member 엔티티 order 정보를 넣는 게 왜 필요한지 설명 부탁드립니다. 감사합니다
-
미해결Spring Cloud로 개발하는 마이크로서비스 애플리케이션(MSA)
서비스 디스커버리 관련 질문입니다.
안녕하세요. 수업 잘 듣고있습니다. 서비스 디스커버리 관련 질문인데요, 스프링 유레카를 클라우드에 올릴때, 1개의 서버(팟)에만 올려야 하는지요? 여러개의 팟에 올려서 등록된 인스턴스가 공유가 가능한건가요? 서버1개에서만 유레카가 돌면 서비스디스커버리 자체의 트래픽이 높아져, 혹은 커넥션이 꽉차 장애가 나는경우가 있지 않을까 해서요. 감사합니다.
-
미해결실전! 스프링 부트와 JPA 활용1 - 웹 애플리케이션 개발
dependencies 에 sourceset 으로 분류되지 않아도 괜찮을까요?
안녕하세요, 강의 잘 듣고 있습니다 :) 다름이 아니라, Gradle 설정 후 sourceset 으로 되지 않고 ClassPath 로 뜨더라고요. 왠만한 설정들은 다 똑같은데 버전 차이인지 모양은 조금씩 다른 것 같습니다. 그대로 진행해도 괜찮을까요? 답변 미리 감사드립니다 :)
-
미해결
JPA 질문
엔티티에 키가 두개이상일 경우 JpaRepository를 extends 할때 JpaRepository<entity, id(의자료형?)>을 써야하는걸로 알고있는데 키가 두개이상이면서 키 두개 모두 자료형이 같을 경우 어떻게 해야 되는지 궁금합니다
-
해결됨실전! 스프링 부트와 JPA 활용1 - 웹 애플리케이션 개발
더티체킹 관련 질문 드립니다.
TB_NOTICE tbNotice = em.createQuery("select n from TB_NOTICE n where n.use_flg = 1 and n.read_flg = 0", TB_NOTICE.class) .getSingleResult();tbNotice.setUseflg(0);//이렇게 실행하면 더티 체킹이 안되는 것 같은데 이유가 있을까요?//반드시 persist된 객체만 더티체킹이 가능한 것 인가요?
-
미해결실전! 스프링 부트와 JPA 활용1 - 웹 애플리케이션 개발
IDENTITY vs SEQUENCE 전략 중 든 의문
안녕하세요, 지금 강의랑 직접적으로 관련된 의문은 아니지만, 지금까지 이 강의를 진행하면 든 의문이 있어서 해소하고 싶어 질문드립니다. DB에 insert을 할 때 사용되는 IDENTITY 전략과 SEQUENCE 전략이 그것인데요. (우선 JPA 강의는 이게 처음이라서 검색을 통해 해소하고 싶었지만 제 검색 실력이 부족해 질문드립니다) 1. 제가 검색을 통해 알아본 결과, GenerationType.IDENTITY는 em.persist() 실행 시점에 DB에 INSERT를 날리고, PK값을 가지고 오고, Sequence는 DB로부터 sequence를 가지고 와서 em.persist()할 때 가지고 온 sequence를 영속성 컨텍스트에 주입한다고 알고 있습니다. 근데 그렇게 할 거면 차리리 그냥 IDENTITY 역시 다음 AUTO_INCREMENT 값이 뭔지만 가져와서 영속성 컨텍스트에 넣고 실제 ISNERT는 flush할 때 넣어주는 방법도 고려해볼 만한 거 같은데 왜 그런 전략은 취하지 않은 건지 의문이 들었습니다. 2. sequence 같은 경우는 allocation_size가 50일 때, 첫 번째 INSERT 쿼리 중 에러가 발생해서 해당 트랜젝션이 종료되면 해당 50개의 sequence는 날라가고 51번째부터 시작하는 건지도 궁금합니다 3. 마찬가지로 IDENTITY 전략에서 em.persist() insert 중 에러가 발생해서 rollback이 되기 전에 다른 insert 요청이 날라와서 insert를 해야하면 처음 에러가 발생했을 때 사용된 PK는 뛰어넘고 auto_increment가 진행되는 건지도 알고 싶습니다.
-
미해결Spring Cloud로 개발하는 마이크로서비스 애플리케이션(MSA)
java.lang.NoClassDefFoundError: Could not initialize class javax.xml.bind.DatatypeConverterImpl 에러 대처법
- 학습 관련 질문을 남겨주세요. 상세히 작성하면 더 좋아요! - 먼저 유사한 질문이 있었는지 검색해보세요. - 서로 예의를 지키며 존중하는 문화를 만들어가요. - 잠깐! 인프런 서비스 운영 관련 문의는 1:1 문의하기를 이용해주세요. private boolean isJwtValid(String jwt) { boolean returnValue = true; String subject = null; try { subject = Jwts.parser().setSigningKey(env.getProperty("token.secret")) .parseClaimsJws(jwt).getBody() .getSubject(); }catch (Exception ex){ returnValue = false; } if(subject==null || subject.isEmpty()){ returnValue = false; } return returnValue;} 이부분에서 디버깅을 따라가던중 getBody() 메서드에서 오류가 발생하는것을 발견 하였습니다. java.lang.NoClassDefFoundError: Could not initialize class javax.xml.bind.DatatypeConverterImpl 이러한 오류가 발생하였을때 pom.xml에 <dependency> <groupId>javax.xml.bind</groupId> <artifactId>jaxb-api</artifactId> <version>2.1</version> </dependency> 해당 종속성을 추가해주게 되면 해결됩니다. 혹시 저같은 오류가 발생하신 분들에게 도움이 되었으면 좋겠습니다~! 음 뒷강의에서.... 바로 추가해주시는군요 ...ㅎㄷㄷ....
-
미해결실전! 스프링 부트와 JPA 활용2 - API 개발과 성능 최적화
jpql 페치조인
안녕하세요 영한님 감사합니다 첫번째 : new 명령어를 사용해서 JPQL의 결과를 DTO로 즉시 반환하면 SELECT 절에서 원하는 데이터를 직접 선택하므로 네트워크 용량을 최적화 할수 있다고 해주셨는데 뒤로 돌아가서 JPQL 페치조인도 마찬가지로 원하는 데이터를 직접 선택해 보고싶어서 이런식으로는 못하나요 ? 테스틀 해봤는데 에러가 나서 질문드립니다. ======================================== 두번쨰 : 18:40 설명은 xToOne 관계에선 페치조인이 필요 없다고 이해 하면 되는거죠 ???
-
미해결Spring Cloud로 개발하는 마이크로서비스 애플리케이션(MSA)
설정 정보가 다른 CircuitBreaker 사용하는 방법
안녕하세요. 강의 잘 듣고 있습니다. 예제에서 Resilience4jConfig를 통해 CircuitBreaker에 대한 설정을 하여 사용하는 것으로 확인을 했습니다. MSA를 연동하는 서비스에 따라 CircuitBreaker에 대한 설정 값을 다르게하여 복수개를 사용하는 경우도 있을 것 같은데, 이럴 경우 Resilience4JConfig에 대한 Bean 등록과 Config 를 어떻게 잡으면 될까요? 감사합니다.
-
미해결실전! Querydsl
concat() stringValue 나이를 완전히 가져오지 못합니다.ㅠㅠ
안녕하세요 질문이 있습니다 concat을 사용해서 stringValue를 활용할 때 나이를 다 가져오지 못하고 맨 앞에 있는 숫자만 가져오는데 왜 그럴까요ㅠㅠㅠㅠ
-
미해결자바 ORM 표준 JPA 프로그래밍 - 기본편
상속 매핑에 대한 질문
안녕하세요 영한님 서포터즈님들 상속 매핑에 대해 예제를 작성하는 중에 궁금한 점이 생겨 질문드립니다. 제가 게시판을 생성해서 게임 게시판. 일정 게시판 등 종류 별로 만들 때, 어떤 전략을 사용하는게 효율적인가 생각해보았습니다. 현재 자식 게시판들은 모두 같은 필드를 가지고 있습니다. 즉, 부모 게시판에 있는 필드만을 사용합니다. 1. SINGLE TABLE 전략 해당 전략을 사용하게 된다면 부모 테이블에 자식 테이블의 필드들이 한 테이블에 있게 됩니다. 특정 게시판을 조회하기 위해서는 모든 게시판 객체를 가져올텐데, 시스템의 규모가 크지 않고, join할 필요가 없기 때문에 현재는 해당 방법이 효율적이라 생각합니다. 2. JOIN TABLE 전략 추후에 게시판들이 늘어나게 되고, 다른 게시판 종류의 추가로 필드를 추가할 필요가 있다고 가정해봤습니다.(확장성 고려) 그렇다면 1번 전략을 사용할 때, 특정 게시판을 조회하기 위해서는 모든 게시판을 다 탐색해야하는데,조인 전략을 사용하게 되면 특정 게시판을 조회할 때 그 특정 게시판 테이블만 조회하면 된다고 생각합니다. 따라서 게시판들이 늘어나게 되면 해당 방법이 효율적이라 생각합니다.결론 그래서 제가 예제를 만들 때 사용한 전략에 대해 저 자신을 위와 같은 이유로 납득시켰는데 이게 맞는지 궁금합니다 그렇다면 결국 대부분의 실무에서는 JOIN 전략을 사용할 수 밖에 없나요?
-
미해결실전! 스프링 부트와 JPA 활용2 - API 개발과 성능 최적화
OrderItems까지 같이 조회되는 이유가 궁금합니다!
안녕하세요 항상 좋은 답변 남겨주셔서 감사합니다 OrderItems까지 같이 조회되는 이유가 궁금해서 글을 적게 되었습니다. @GetMapping("/api/v1/simple-orders")public List<Order> ordersV1() { List<Order> orders = orderService.findOrders(new OrderSearch()); orders.forEach(order -> { order.getMember().getName(); order.getDelivery().getStatus(); }); return orders;} V1 컨트롤러는 다음과 같습니다. @Entity@Getter@Setter@NoArgsConstructor@AllArgsConstructor@Table(name = "orders")public class Order { @Id @GeneratedValue @Column(name = "order_id") private Long id; @ManyToOne(fetch = FetchType.LAZY) @JoinColumn(name = "member_id") private Member member; @OneToMany(mappedBy = "order", fetch = FetchType.LAZY, cascade = CascadeType.ALL) // order가 만들어지면 orderItem이 만들어지기 때문에 영속성 전이한다. private List<OrderItem> orderItems = new ArrayList<>(); @OneToOne(fetch = FetchType.LAZY, cascade = CascadeType.ALL) private Delivery delivery; private LocalDateTime orderDate; @Enumerated(EnumType.STRING) private OrderStatus status; ORDER는 다음과 같습니다. @Entity@Getter@Setterpublic class OrderItem { @Id @GeneratedValue @Column(name = "orderitem_id") private Long id; @ManyToOne(fetch = FetchType.LAZY) @JoinColumn(name = "item_id") private Item item; @JsonIgnore @ManyToOne(fetch = FetchType.LAZY) @JoinColumn(name = "order_id") private Order order; private int orderPrice; private int count; ORDER_ITEM은 다음과 같습니다. 여기서 V1 컨트롤러를 통해서 쿼리를 날리면, 뒤늦게 Lazy Loading을 통해서 Order_Item들이 프록시 초기화가 되는 것처럼 나갑니다. 그런데 실제로는 프록시가 초기화도 되어있지 않습니다. 정리하면 이렇습니다 1. Order_Items는 Lazy Loading 설정이 되어있고, 프록시 객체를 강제 초기화 하는 과정도 없습니다. 그런데 왜 select 쿼리가 나가게 되는 것인지 알려주실 수 있으실까요? 2. orderItem에 대한 select 쿼리가 나갔음에도 불구하고 실제 응답에 있는 값은 null입니다. 이 경우는 어떻게 이해를 해야할까요? 항상 좋은 답변 주셔서 감사합니다!
-
미해결실전! 스프링 부트와 JPA 활용2 - API 개발과 성능 최적화
@Transactional이 생략되는 이유가 궁금합니다
안녕하세요. 항상 좋은 답변 해주셔서 감사합니다. 이번에는 @Transactional이 생략되는 이유가 궁금해서 글을 적게 되었습니다. @GetMapping("/api/v4/simple-orders")public List<SimplerOrderQueryDto> ordersV4() { return orderSimpleQueryRepository.findOrderDtos(); } @Repository@RequiredArgsConstructorpublic class OrderSimpleQueryRepository { private final EntityManager em; public List<SimplerOrderQueryDto> findOrderDtos() { return em.createQuery( "select new jpabook.jpashop.repository.order.simplequery.SimplerOrderQueryDto(o.id, m.name, o.orderDate, o.status, d.address) from Order o" + " join o.member m" + " join o.delivery d", SimplerOrderQueryDto.class ).getResultList(); }} V4 컨트롤러를 개발할 때 궁금한 내용입니다. em.createQuery를 만들어서 dto를 바로 조회해오는 내용입니다. 제가 궁금한 부분은 @Transactional이 없어도 정상동작하는 부분입니다. 위 코드 상에는 어디에도 tx.begin() / tx.commit()이 되어있는 부분이 없는 것으로 보입니다. 따라서 트랜잭션 상태가 아니기 때문에 JPA가 DB 커넥션을 얻지 못한 상황으로 보이는데, DB에서 값을 읽어오고 있습니다. 혹시 어떤 조화로 이렇게... 트랜잭션 없이 값을 불러오는것인지.. 그리고 영속화가 되고 있는것인지를.. 알려주실 수 있으실까요? 감사합니다!
-
해결됨실전! 스프링 부트와 JPA 활용1 - 웹 애플리케이션 개발
실무에서 사용되는 Setter
학습하는 분들께 도움이 되고, 더 좋은 답변을 드릴 수 있도록 질문전에 다음을 꼭 확인해주세요.1. 강의 내용과 관련된 질문을 남겨주세요.2. 인프런의 질문 게시판과 자주 하는 질문(링크)을 먼저 확인해주세요.(자주 하는 질문 링크: https://bit.ly/3fX6ygx)3. 질문 잘하기 메뉴얼(링크)을 먼저 읽어주세요.(질문 잘하기 메뉴얼 링크: https://bit.ly/2UfeqCG)질문 시에는 위 내용은 삭제하고 다음 내용을 남겨주세요.=========================================[질문 템플릿]1. 강의 내용과 관련된 질문인가요? (예/아니오)2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예/아니오)3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예/아니오)[질문 내용]Setter를 열어 둘 경우 엔티티에 변경으로 인한 유지보수가 힘들다고 말씀해주셨는데 혹시 Setter를 다 닫고 필요한 것만 연다거나, 비즈니스 메서드를 만드는 예제를 참고할 만한게 있을까요?
-
미해결스프링 입문 - 코드로 배우는 스프링 부트, 웹 MVC, DB 접근 기술
javax.persistence.Enetity import 안 됩니다.
=========================================[질문 템플릿]1. 강의 내용과 관련된 질문인가요? (예)2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예)3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예)[질문 내용]1. 상황 -스프링입문 강의에서JPA 강의 영상 중 - 강사님 안내에 따라 build.gradle, application.properties에 반영했습니다. 2. 문제: javax.persistence.Entity가 라이브러리로 동작하지 않음. 빨간색으로 되어 있고 라이브러리를 import할 수 도없습니다. 답변에 미리 감사합니다.
-
미해결자바 ORM 표준 JPA 프로그래밍 - 기본편
batchSize 원리에 대해서 알고 싶습니다
안녕하세요 영한님 @BatchSize를 이용하여 최적화를 하다가 문득 깊은 내용을 알고싶어서 질문을 드립니다. 폴더 안의 폴더를 만드는 구조인데요 다음의 상하 관계를 가진 폴더가 총 13개 있습니다. 이 13개의 폴더 정보를 받아 위의 그림의 구조로 저장을 하고 싶었습니다 . @Getter@NoArgsConstructor(access = AccessLevel.PROTECTED)@Entitypublic class Folder { @Id @GeneratedValue(strategy = GenerationType.SEQUENCE) @Column(name = "FOLDER_ID") private Long id; private String name; // 부모 @ManyToOne(fetch = FetchType.LAZY) @JoinColumn(name = "PARENT_ID") private Folder parent; // 자식 @BatchSize(size = 900) @OneToMany(mappedBy = "parent") private List<Folder> children; @Builder private Folder(String name, Folder parent) { this.name = name; this.parent = parent; } } 그래서 Folder라는 엔티티를 self reference하도록 구성을 했구요 @BeforeEachpublic void setUp() throws Exception { Folder aFolder = Folder.builder() .name("A") .build(); Folder bFolder = Folder.builder() .name("B") .parent(aFolder) .build(); Folder bChild1 = Folder.builder() .name("BChild1") .parent(bFolder) .build(); Folder bChild2 = Folder.builder() .name("BChild2") .parent(bFolder) .build(); Folder bChild3 = Folder.builder() .name("BChild3") .parent(bFolder) .build(); Folder cFolder = Folder.builder() .name("C") .parent(aFolder) .build(); Folder cChild1 = Folder.builder() .name("CChild1") .parent(cFolder) .build(); Folder cChild2 = Folder.builder() .name("CChild2") .parent(cFolder) .build(); Folder cChild3 = Folder.builder() .name("CChild3") .parent(cFolder) .build(); Folder dFolder = Folder.builder() .name("D") .parent(aFolder) .build(); Folder dChild1 = Folder.builder() .name("DChild1") .parent(dFolder) .build(); Folder dChild2 = Folder.builder() .name("DChild2") .parent(dFolder) .build(); Folder dChild3 = Folder.builder() .name("DChild3") .parent(dFolder) .build(); folderRepository.saveAll(Arrays.asList(aFolder, bFolder, cFolder, dFolder, bChild1, bChild2, bChild3, cChild1, cChild2, cChild3, dChild1, dChild2, dChild3)); em.flush(); em.clear();} 이렇게 저장을 한 후 @Test@DisplayName("bfs 알고리즘 적용 테스트")@Transactional@Commitpublic void bfsTest() throws Exception { // given Queue<Folder> queue = new LinkedList<>(); Folder deleteFolder = folderRepository.findById(1L).get(); queue.offer(deleteFolder); List<Folder> tempFolders = new ArrayList<>(); tempFolders.add(deleteFolder); int i = 0; // when while(!queue.isEmpty()) { System.out.println("i = " + i); Folder pollFolder = queue.poll(); List<Folder> folders = pollFolder.getChildren(); for (Folder folder : folders) { queue.offer(folder); } tempFolders.addAll(folders); i++; } // then Collections.reverse(tempFolders); folderRepository.deleteAll(tempFolders); em.flush();} 위의 코드처럼 테스트 코드를 짯습니다 그러니 select 쿼리가 많이 줄어든것을 확인할 수 있었습니다. 2022-01-13 23:25:04.471 DEBUG 21588 --- [ main] org.hibernate.SQL : select folder0_.folder_id as folder_i1_1_0_, folder0_.name as name2_1_0_, folder0_.parent_id as parent_i3_1_0_ from folder folder0_ where folder0_.folder_id=? 2022-01-13 23:25:04.492 DEBUG 21588 --- [ main] org.hibernate.SQL : select children0_.parent_id as parent_i3_1_1_, children0_.folder_id as folder_i1_1_1_, children0_.folder_id as folder_i1_1_0_, children0_.name as name2_1_0_, children0_.parent_id as parent_i3_1_0_ from folder children0_ where children0_.parent_id=? 2022-01-13 23:25:04.498 DEBUG 21588 --- [ main] org.hibernate.SQL : select children0_.parent_id as parent_i3_1_1_, children0_.folder_id as folder_i1_1_1_, children0_.folder_id as folder_i1_1_0_, children0_.name as name2_1_0_, children0_.parent_id as parent_i3_1_0_ from folder children0_ where children0_.parent_id in ( ?, ?, ? ) 2022-01-13 23:25:04.501 DEBUG 21588 --- [ main] org.hibernate.SQL : select children0_.parent_id as parent_i3_1_1_, children0_.folder_id as folder_i1_1_1_, children0_.folder_id as folder_i1_1_0_, children0_.name as name2_1_0_, children0_.parent_id as parent_i3_1_0_ from folder children0_ where children0_.parent_id in ( ?, ?, ?, ?, ?, ?, ?, ?, ? ) 총 이렇게 4개의 쿼리가 나갔는데요 서론이 길었습니다 선생님 제가 질문할 것은 이겁니다 @BatchSize를 설정하면 하이버네이트는 어떤 알고리즘으로 저 in절의 아이디 값들을 넣는 것일까요> 자료를 찾아봐도 나오는데가 없었고 저스스로 고민을 했을 때는 <1번> 첫번째 select 쿼리가 나갔을 때 A폴더(id = 1)가 영속화 된다. <2번> 2번째 select 쿼리가 나갔을 때 B,C,D 폴더 즉 id가 2,3,4인 폴더들이 영속화가 된다. -> 따라서 3번째 select 쿼리에서 in절의 id들은 이 2,3,4가 되는 것이다. (여기서의 의문점 그럼 앞서 영속화된 A폴더의 id = 1은 안 집어 넣는 알고리즘은 또 뭘까) 이렇게 생각했는데 과연 맞는지 궁금합니다