월 17,600원
5개월 할부 시다른 수강생들이 자주 물어보는 질문이 궁금하신가요?
- 미해결실전! 스프링 데이터 JPA
DTO로 조회시 DTO의 조회 위치는 어디가 되면 좋을까요..?
안녕하세요 강의를 보던 도중 의문이 생겨서 질문남깁니다. Layerd Architecture 에서 Controller, Service, Repository로 역할을 구분해서 레이어당 커플링을 줄이도록 하고 있는 알고 있습니다. 그런데 DTO 의 사용위치 (해당 DTO는 사용자 API)에 대해 궁금한 점이 있습니다. JPA에서 DTO로 조회하면 편하게 데이터를 가져 올수 있는데 해당 DTO가 서비스 혹은 Application Layer에 커플링이 생기는데 이럴 경우는 어떻게 해결해야 될까요..? DTO 자체를 Service DTO, 와 Controller DTO로 분리하여 컨버팅을 해주어야 되는지 아니면 Controller 에서 Repository 를 직접 사용해도 되는 예외상황을 고려해야될지가 고민입니다. 아니면 엔티티를 조회한후 필요한 부분만 DTO로 변환을 하는지 그것도 아니면 Object 객체로 조회한후 Object 안에서 데이터를 추출하는지 어떤 방법을 사용하시는지가 궁금합니다. 보통 이런 경우에는 어떻게 처리하는게 효율적인 방법일까요..? 시스템 개발을 하다가 서비스로 커리어 전환을 하고 있는데 김영한님 강의가 너무 재밌어서 계속 찾아보게 되네요 ㅎ
- 미해결실전! 스프링 데이터 JPA
findAll 조인된 데이터까지 한번에 조회하기
[질문 템플릿]1. 강의 내용과 관련된 질문인가요? (예)2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예)3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예)[질문 내용]안녕하세요. JPA 강의 잘 듣고있습니다! JPA를 통해 개발을 하던 중 궁금한 점이 생겨서 문의드립니다. 현재 상태는 @ManyToOne 양방향 매핑을 해둔 상태인데요. 궁금한 점을 쉽게 설명드리기 위해서, 간략한 샘플코드를 작성해보았습니다. // Entity @Getter @Setter @Table(name="group") @Entity public class Group { @Id private Integer id; @ManyToOne(fetch=FetchType.LAZY) @JoinColumn(name="category_id") private Category category; } @Getter @Setter @Table(name="category") @Entity public class Category { @Id private id; private String name; @OneToMany(mappedBy="category", cascade=CascadeType.ALL) private List<Group> groups; } // Repository public interface GroupRepository extends JpaRepository<Group, Integer>{ } GroupRepository.findAll(); 을 호출 할 경우 발생되는 쿼리를 확인해보았더니 >>> select id, name, category_id from group g left outer join category c on g.category_id = c.id 이때, 한번에 category_name 까지 쿼리로 날리는 방법이 있을까요? 현재는 ModelMapper 를 통해 findAll()로 조회한 데이터를 가지고 DAO에서 DTO로 mapping하는 과정에서 쿼리가 추가적으로 호출되고 있습니다. >>> select id, name from category where id=? >>> select id, name from category where id=? >>> select id, name from category where id=? (카테고리 ID갯수만큼 쿼리를 호출함) 제가 원하는 처리과정은 쿼리 한번에 category_name 까지 가져오는것인데, ( >>> select id, name, category_id, category_name from group g left outer join category c on g.category_id = c.id ) 다음과 같은 쿼리로 한번에 조회할 수 있는 방법이 있는지, 그리고 제가 작성한 매핑이나 코드가 잘못된 것이 있는지,, 궁금합니다, 피드백 부탁드립니다. 감사합니다.
- 미해결실전! 스프링 데이터 JPA
@EntityGraph 관련 문의드립니다.
Spring Data Jpa에서 @EntityGraph는 left outer join(fetch)만 가능한건가요? inner join(fetch)을 사용하고 싶으면 JPQL을 이용해야할까요?
- 미해결실전! 스프링 데이터 JPA
복합키 식별관계 재질문입니다.
안녕하세요 김영한님! 자유주재로 올렸다가 요청해주신것에 따라서 질문으로 옮겼습니다. 현재 spring data jpa로 진행중이며 간략한 엔티티 및 관계 정의는 아래와 같습니다. Entity A [primary key A1, A2] / LectureType.class IdClassA [A1, A2] Entity B [primary key A1, A2, B1] / ManyToOne 단방향 관계, fetch lazy / ExamType.class IdClassB [IdClassA, B1] ex) BeforeAll로 A,B 더미 데이터를 저장 @Transactional @Test Brepository.findAll(); Brepository.findAll(); B Repository로 findall을 두번호출했을때 ( 다른 코드는 없습니다 ) identifier of an instance of B was altered from BIdClass@90c990a9 BIdClass@21b621d7 와 같이 예외가 발생했습니다. (키 값을 변경하려고 시도한적도 없습니다) 이와 관련해서 제가 개념을 잘못 익힌것인지, 검색 컨셉을 잘못잡은것인지 모르겠지만, 검색해도 잘 안나오더라구요. 각 엔티티의 주키를 string으로 직접 저장하는것 때문인지, 정확한 문제를 모르겠습니다. 공유 링크 : https://drive.google.com/file/d/1fnbHq8i1gcZC0eWFuCYolDnRzwOqio2x/view?usp=sharing 실행 방법 : spring data jpa 강의를 그대로 따라 한것이여서 강의에서 설명해주신것과 실행 방식이 다르지 않습니다. 다만 h2 데이터베이스를 별도로 다운받지 않고, 내장된 것을 사용중입니다. application.yml에 정보가 추가 되어 있습니다. 문제 발생되는곳 : test/java/study/datajpa/domain/exam/ExamTypeRepositoryTest 에서 exam_type_crud_check() 테스트 실행하면 에러 내용을 확인 할 수 있습니다. 하나더 궁금한 것이 있는데 id를 직접 넣어서 할때 강의해주신 Persistable<String>을 사용하면 된다고 하셨는데, 복합키 혹은 식별 관계에 있는 복합키일 경우 IdClass를 String 부분에 넣어주면 되는것일까요??
- 미해결실전! 스프링 데이터 JPA
baseEntity와 softDelete 질문
우선 관련 다른 댓글들은 읽고왔는데 더 궁금한 점이 있어 질문드립니다. Q1. baseEntity에서 abstract class를 사용하지 않고 실제 class를 사용하신 이유 softDelete 사용시 springdatajpa 레퍼런스 닥스에서는 엔티티에 delete flag를 만들어주고, @sql로 delete 실행을 delete flag를 true로 만들어주는 방식을 예제로 두고 있습니다. 그러면 baseEntity에서 - 필드 delete flag 선언 -> 전역 엔티티에 적용 - @sql 로 delete 실행 변경 -> 전역정용 - @where절 delete=false -> 전역 적용 이렇게 할 경우 장점으로는 cascade 옵션으로 delete// orphanRemoval에도 자동으로 delete 쿼리가 업데이트 쿼리로 변경되어 삭제 플레그의 연관관계를 보다 쉽게 처리할 수 있는거로 생각됩니다. 또한 필터? 옵션으로서 실제 플레그로 삭제된 엔티티도 조회 가능하도록 제공하는걸 확인했습니다. 관련 다른 댓글에서 답변해주신것을 보면 영한님은 전역 엔티티가 아닌 엔티티별로 메서드를 정의해주고 연관관계가 있을경우 직접 연관관계 메서드에서 해당 메서드를 사용하시는 것으로 추측됩니다. Q2. 그렇게 사용하시는 걸 선호하시는 이유를 알 수 있을까요? 개인적으로 전역으로 관리하는게 좋겠다 싶었던 이유는 사용자에 의해 기록된 모든 데이터가 기업의 입장에서는 엄청나게 큰 자산이고, 이것을 통해 추천 상품 알고리즘을 위한 데이터로 활용할수도 있고 (주문기록, 회원의 나이 등 정보, 관심상품 등등), 어떠한 비즈니스 정책들을 정하는데 큰 도움이 될거라 싶어 실무에서는 플래그로 삭제 하지 않을까? 해서 전역으로 관리 하는게 좋겠다 싶었습니다. 근데 전역으로 저렇게 처리할 경우, 고객 정보같은 민감한 데이터는 실제로 삭제를 해줘야 할것 같은데 (회원 탈퇴시 같은 경우) 회원과 연관관계가 있는 엔티티들이 엄청나게 엮어 있을때 이런 경우는 어떻게 처리해야 좋을지 감이 잡히지 않습니다. 그래서 추가 질문으로는 Q4. 실무에서 softDelete를 어떤 엔티티에 적용하는지 Q5. 회원은 민감한 정보라 실제 삭제를 할때 관련된 연관관계가 있는 엔티티는 어떻게 처리하는게 좋을지 예를들면 member에 null값으로 그냥 냅두는지 이런 것들이 궁금합니다. 답변주시면 정말정말 감사드리겠습니다. 쿼리dsl 강의 듣기전에 datajpa로 이것저것 토이프로젝트를 해보면서 고민해보는데 생각보다 적용함에 있어 고려할것들이 넘쳐나 질문을 많이 하게되네요
- 미해결실전! 스프링 데이터 JPA
프로젝션 사용시 인터페이스 vs 구현체
프로젝션 사용시 인터페이스와 구현체를 모두 사용할 수 있는데 인터페이스의 경우 바로 조회가 필요 없을때 프록시를 담아서 활용할 수 있을거란 예상은 되는데요 어떤 케이스에서 프록시를 사용하는게 도움이 될지, 언제 필요한지 잘 모르겠습니다. 알려주시면 감사드리겠습니다.
- 미해결실전! 스프링 데이터 JPA
flush 질문
12분쯤에 위에 save를 한것들은 영속성컨텍스트에 아직 남아있 그다음 JPQL로 인해 DB에는 41살이 있을텐데 그 이후로 FLUSH를 하면 영속성컨텍스트에 있던 40살이 DB에 반영되서 41 -> 40이 되는게 아닌가요???
- 미해결실전! 스프링 데이터 JPA
단순 조회시 (nested) 페치조인 관련 질문
활용편에서 일대일, 다대일 대상 페치조인의 경우 여러개를 써도 된다고 하셨었는데요 public class Post{ @OneToOne private AAA aaa; .. .. } public class AAA{ @OneToOne private BBB bbb; } 이런 케이스에서 (단순 조회용) "select p from Post p" + " join fetch p.aaa a" + " join fetch a.bbb b" 이렇게 nest join fetch의 경우에는 entity graph를 사용할 수 없는 건가요?
- 미해결실전! 스프링 데이터 JPA
유니크 데이터 조회시 list // optional
유니크 데이터 조회시 반환타입을 list // optional 이렇게 두개로 받을 수 있는데, 개인적으로는 optional의 경우 orElseThrow를 통해 예외를 던지거나 원하는 예외로 던질 수 있어 이쪽이 선호되는데 1. 반환타입은 사용하는 사람 취향일까요 아니면 좋은 방식이 있을까요? 2. 기본적으로 스프링이 던지는 예외를 사용하는게 좋을까요 커스텀으로 예외를 만들어 주는게 좋을까요? 답변주시면 감사드리겠습니다.
- 미해결실전! 스프링 데이터 JPA
페이징 처리 질문
안녕하세요! 페이징 챕터를 보다 궁금한게 있어서 질문드립니다. 강의 처음에 영한님이 MemberRepository에 Page<Member> findByAge(int age, Pageable pageable); 이렇게 만들고 아무이상없이 사용하셨습니다! 그래서 제가 코드를 약간 수정하여 파라미터 값으로 age를 빼고 pageable만 받도록 코드를 수정하여 코드를 실행하니 오류가 발생했습니다. 원인을 찾다가 혹시나 싶어서 @Query("select m from Member m") 어노테이션을 달아주니 그제서야 정상적으로 작동했는데 원인이 무엇인지, 또 이렇게 사용하는게 올바르게 사용하는건지 궁금해서 질문드립니다! 수정한 최종 코드는 아래처럼 변경해서 사용했습니다! @Query("select m from Member m")Page<Member> findMemberPage(Pageable pageable);
- 미해결실전! 스프링 데이터 JPA
안녕하세요! Exception 관련 질문드립니다!
안녕하세요! 6월 방학부터 개학한 오늘까지 김영한님의 모든 강의를 들으며 많은 깨달음을 얻고 실력을 키웠습니다. 먼저, 정말 좋은 강의를 해주셔서 감사하다는 말씀을 드립니다! 제가 질문드리고 싶은건 NoResultException입니다! JpaReopsitory<T,ID>를 상속받는 레포지토리는 Member findByUsername(String username) 를 하고 memberRepository.findByUsername("DB에 없는 username") 을 할시에 null이 들어가면서 exception이 터지지 않는데 MemberRepository.java public Member findByUsernmae(String username) { return em.createQuery("select m from Member m where m.username=:username", Member.class) .setParameter("username", username) .getSingleResult();} memberJpaRepository.findByUsername("DB에 없는 값")을 할시에는 Exception이 터집니다. 먼저, Repository 내에서 NoResultException이 터지고 Repository에서 나갔을때는 EmptyResultDataAccessException이 터지는거에 궁금했었는데 이건 방금 강의에서 말씀해주셔서 아! 하고 알았습니다. 하지만, JpaRepository를 상속받은 레포지토리는 같은 쿼리를 날리지만 어떤 원리로 exception이 터지지 않고 null이 들어가는지 궁금합니다! 혹시, JpaRepository인터페이스를 구현한 클래스에서 Exception을 잡은다음에 null로 뿌려주는것일까요? 감사합니다!
- 미해결실전! 스프링 데이터 JPA
fetch 조인의 sql 번역시 inner, outer 결정방법
fetch조인시 기본으로 left outer join으로 실행된다고 강의 20:12 쯤에 말씀해주셨습니다. 강의실습으로 선생님께서 확인을 해주셨는데요. 기본편 강의에서 실습을 할 때는 분명 inner join 이였던 걸로 기억을 해서 여러 블로그 글과 책(p.374 상단 실행된 SQL)을 확인해봤습니다. 이때는 inner join으로 설명이 됐는데요. fetch조인을 sql번역했을 때 inner join / outter join 둘 중 어떤 것을 택하는지 그 결정 방식이 궁금합니다.
- 미해결실전! 스프링 데이터 JPA
fecth join
안녕하세요 강사님 좋은 강의 감사 드립니다. fetch join 이 한마디로 연관된 테이블을 모드 끌어온다 라고 말씀 해주셨는데.. 제가 예전에 따로 혼자 배울때 엔티티 속성에 fetch type = EAGER이런식으로 eager 을 하면 이것 또 한 연관된 테이블 다 불러오는거로 제가 기억하는데 이 둘은 무슨 차이인가요?.. 아니면 제가 EAGER에 대해 잘못 알고 있는 걸까요??ㅠㅠ
- 미해결실전! 스프링 데이터 JPA
결과 리스트의 size() vs count 쿼리
count 쿼리가 나가는 이유가 궁금합니다. Select 결과로 받아온 리스트의 size()를 실행시키는 게 count 쿼리를 다시 날리는 것보다 비용이 적을 것 같은데, count 쿼리가 다시 나가는 이유가 궁금합니다 :) 강의는 늘 즐겁게 듣고있습니다 감사합니다!
- 미해결실전! 스프링 데이터 JPA
UsernameOnlyDto
안녕하세요 영한님 항상 감사합니다. //when List<UsernameOnlyDto> result = memberRepository.findProjectionsByUsername("m1"); 이부분에서 전달 인자로 "m1" 을 넣으셨는데 List<UsernameOnlyDto> findProjectionsByUsername(@Param("username") String username); 이부분에선 m1이 Member 의 필드라는 힌트도 없는데 어떻게 Member 엔티티로 m1이 매핑이 되는건가요 ?? public UsernameOnlyDto(String username){ this.username = username; } 만약에 username 이 부분이라면 다른 곳에서도 똑같은 username 의 필드가 중복이 되있을수도 있지않나요?
- 미해결실전! 스프링 데이터 JPA
paging시 정렬 조건에 count관련한 문제로 질문이있습니다. 존경하는 선생님
존경하는 선생님,, 현재 페이징 관련 코드를 작성하는 와중 저의 이해가 부족한듯 하여 이렇게 질문을 남깁니다.. 어떤 포스트 entity와 좋아요 entity가 1:N 관계를 가지고 있는 상황에서 repository에서 @query로 정렬조건을 다 작성해서 "order by post.userPostLikes.size desc"이런식으로 정렬하면 가능하지만 이런 방식은 재사용이 불가능하여 쿼리 메서드를 사용한 상태에서 Pageable만 사용해서 desc,asc,페이지 사이즈 등등 프론트단에서 선택적으로 받을수 있도록 하고싶은데 이런 상황에서 쿼리 스트링으로 sort=userPostLikes.size,desc 이런식으로 보내도 원하는 방식대로 동작하지 않습니다. 이런 상황에서 제가 처음에 한 방식대로 @query를 사용해서 직접 정렬 조건을 작성하는 것 말고 pageable을 사용한 다른 방식이 있을까요?
- 미해결실전! 스프링 데이터 JPA
변경감지
안녕하세요 영한님께서 가급적이면 merge 를 쓰면 안된다고 말씀하셨는데 JPA 에서 변경감지 기능 사용, 이것도 결국 내부에서 merge를 호출하는거 아닌가요?? 직접 merge를 호출하지 말라는 말씀이신가요?
- 미해결실전! 스프링 데이터 JPA
Slice
안녕하세요 영한님 감사합니다 PageRequest pageRequest = PageRequest.of(0, 3, Sort.by(Sort.Direction.DESC, "username")); Slice<Member> page = memberRepository.findByAge(age,pageRequest); ------------------------------------------------------- 결과: select member0_.member_id as member_i1_0_, member0_.age as age2_0_, member0_.team_id as team_id4_0_, member0_.username as username3_0_ from member member0_ where member0_.age=? order by member0_.username desc limit 4 ======================================== 질문 1. limit4 로 DB 를 쿼리를 날리는데 그런데 콘솔에서 데이터를 찍어보면 member=Member(id=5, username=member5, age=10) member=Member(id=4, username=member4, age=10) member=Member(id=3, username=member3, age=10) 이렇게 3건이 나오는데 중간에 JPA가 DB의 쿼리문과는 다르게 중간에 변환을 시켜주는것인가요 ? 질문 2 Slice 는 다음페이지 여부를 위해 Slice (count X) 추가로 limit + 1을 조회하는데, 이전에 페이징에서 사용한 page.hasNext(); 이 메서드를 쓰면 되는거 아닌가요? ? [(totalcount) 를 가져오지 않아서 성능상 유리해서 사용하는것인가요 ?]
- 미해결실전! 스프링 데이터 JPA
@Modifying(flushAutomatically="true/false") 에 대한 질문
안녕하세요! 좋은 강의 잘 듣고 있습니다. 해당 질문 게시판에 있는 @Modifying 의flushAutomatically 에 대한 질문에 대한 답을 보면서 추가로 궁금한 점이 생겨 질문을 남기게 되었습니다. flushAutomatically은 디폴트 값이 false이며 이 값이 true로 의미있게 사용되는 경우는, 1)하이버네이트 옵션에서 JPQL 실행시 강제로 플러시가 되지 않도록 설정할때, flushAutomatically 설정값을 true로 만들경우, 자동으로 flush가 됨 2)JPQL 실행시 모든 내용을 다 플러시 하는것이 아닌 해당 JPQL과 관련있는엔티티만을 플러시함 이때 clearAutomatically를 할경우, 데이터베이스에 JPQL과 관련이 없지만 변경된 데이터가 반영되지 않을 수 있음 이때 flushAutomatically=true 를 사용함으로 이해를 했습니다. (영한님 답변을 통한이해) flushAutomatically =false / true 값에 따른 차이를 눈으로 확인해보고 싶어 테스트 하던중 궁금한 점이 생겼습니다. 2)에 대한 궁금한 점인데요, Member 엔티티와 전혀 관련없는 Pra라는 엔티티를 만들고, 해당 엔티티에서 사용할, Repository또한 만들었습니다. 그리고 멤버 엔티티에 대한 벌크성 쿼리를 test할 경우 위의 PraRepository.save()에 대한 쿼리가 memberRepository.bulkAgePlus() 해당 부분 문장을 실행할때 DB에 반영되지 않고 영속성컨텍스트에만 남아 있을것이라 예상했습니다. (왜냐 멤버관련 벌크성 쿼리와 관련없는 것이기 때문) 하지만 Pra 에 관한 insert query가 발생한 것을 보았습니다.JPQL과 관련없는 엔티티인데, Member 관련 벌크성 쿼리시 다른 엔티티인 Pra 관한 내용 또한 DB에 반영되는 이유가 궁금합니다...!
- 미해결실전! 스프링 데이터 JPA
사용자 정의 리포지토리 구현 방법 관련 질문
안녕하세요? 김영한 강사님.제가 Windows 계열의 웹개발만 하다가 이번 Java 웹개발을 시도하면 강의를 접하게 되었는데.. 이렇게 좋은 강의를 들을 수 있게 해주셔서 무한한 감사드립니다. ㅎㅎㅎ 강의를 듣고 사용자정의 레포지토리 구현방법에 대한 궁금증이 생겨서 이렇게 글을 남김니다. 강의에서 JpaRepository 인터페이스를 상속받은 인터페이스에 일부 확장 쿼리문을 만들고querydsl, native query등의 확장은 xxxxImpl 식으로 확장해서 만들고 있습니다. 이점이 제가 보기에는 많이 번거롭다는 느낌이 들었습니다. JpaRepository 인터페이스의 구현체인 SoleoSimpleJpaRepository 클래스를 직접 상속받아서 확장하면 더 편리하지 않을까 하는 생각이 들었습니다. 구현체가 다양한 것도 아닌듯 하고 Hibernate로 거의 고정되어 있는 듯한데 편리성을 고려해서 이렇게 진행한다면 제가 생각하지 못한 문제점 들이 있는지 문의 드립니다. 제가 아직은 지식이 짧아서 질문이 적절한지는 모르겠으나 시간 허락되시면 답변 부탁드리겠습니다. 감사합니다.