실전! 스프링 데이터 JPA

실전! 스프링 데이터 JPA

(56개의 수강평)

844명의 수강생
Back-EndJavaSpringSpring BootJPASpring Data JPA
월29,333원
88,000원
3개월 할부시
지식공유자 · 김영한
32회 수업· 총 7시간 17분수업
평생 무제한 시청
수료증 발급 강의
수강 난이도 중급이상
kangsy763 프로필

Member member로 바로 받아서 출력 질문있습니다! kangsy763 5일 전
안녕하세요 영한님. 진행 중에 출력이 잘 되지 않아서 질문드립니다. @GetMapping("/members2/{id}") 이 부분을 Member member로 바로 받아서 return member.getUsername()을 해보니깐 1 만 출력이 되길레 member 를 print 해보았더니Member(id=null,username=1,age=0) 라고 뜹니다.DB에는 정확히 들어가 있는 것은 확인되는 상태입니다.  무엇이 문제일까요 ??

2
GPK 프로필

JPA/Hibernate 관련 property 문의 GPK 6일 전
안녕하세요. 매번 친절한 답변 감사드립니다~ 상용 서비스에 적용한다고 할 때  JPA/Hibernate 관련 property 들 중에서 특별히 주의해서 설정해줘야할 것들이 있을까요? 강의에서 말씀해주신대로 DDL 관련 property들은 none으로 해줘야하고, open-in-view 같은 것에 대한 설정값,  dialect들은 실제 운영DB에 맞게 명시적으로 설정해주는 것이 더 좋나요? 현업에 적용시 주의해야할 property들이 또 있는지, 또는 특별히 설정해서 사용하시는 property가 있는지 궁금합니다.

2
kangsy763 프로필

마지막 부분 질문드립니다. kangsy763 6일 전
안녕하세요 !! 마지막 부분 궁금한 점이 생겨서 질문드립니다. 벌크를 사용하면 db에 바로 때려버린다고 하셨는데, //given ~~~~~ 5개 //when int resultCount=memberRepository.bulkAgePlus(20); em.flush(); em.clear(); 이 상황에서 먼저 벌크연산을 통해 db 값을 수정을 하고, flush와 clear 연산을 하게되는데, 이 상황에서의 flush 연산의 동작이 궁금합니다. 책에 따르면, 변경 감지가 동작해서 영속성 컨텍스트에 있는 모든 엔티티를 스냅샷과 비교해서 수정된 엔티티를 찾는다. 수정된 엔티티는 수정 쿼리를 만들어 쓰기 지연 SQL 저장소에 등록한다. 이 쿼리를 db에 전송한다. 라고 나와 있습니다. 먼저, save를 하는 과정에서 persist 한 member들 중 20이 넘는 것들은 member3  20member4 21member5 40 이 있습니다. persist 이후 bulk연산으로 db에 바로 값을 변경시키고, flush에 들어서게 되면 스냅샷 자체는 20,21,40 으로 되어있고 영속성컨텍스트에 따로 값을 변경하지 않았으니 수정된 엔티티를 찾지 못하고, 수정쿼리를 만들어서 지연 SQL 저장소에 등록하지도 않았을 것이고, 이곳에 등록된 것이 없으니 db에 전송하는 쿼리문도 없기 때문에 bulk 연산으로 수정된 값이 남게 되는 것인가요 ? 그렇다면 이 부분에서 flush는 스냅샷과의 비교를 했을 뿐 변경된 엔티티를 감지하지 못하였기 때문에 사실상 비교의 역할만 했다고 볼 수 있는건가요? 제가 이해한게 맞나 궁금합니다!! 긴 질문 읽어주셔서 감사합니다.

4
kangsy763 프로필

totalcount 질문 드립니다. kangsy763 7일 전
안녕하세요!!! 20분대에서 말씀하시는 totalCount를 가져오는데에 있어 말하는 성능이슈는 page.getTotalElements와 연관이 있는건가요 ??  그렇다면 count 쿼리를 분리하였을 때에 getTotalElements() 메서드는 이 분리한 count쿼리에서 결과값을 가져오는 것인가요 !?

1
kangsy763 프로필

JpaRepository 기본 메서드에 대해 kangsy763 7일 전
안녕하세요! 이번강의를 듣다가 궁금한 점이 있었습니다. 메서드의 이름을 통해 자동으로 내부가 구현되어서 동작을 할 수 있는데, 그렇다면 기존에 선언이 되어있는 save 라던가 delete 이런 것들도 동일한 방식으로 즉각적으로 구현이 되어서 동작이 이루어지는 건가요 ?? 

1
변지수 프로필

안녕하세요 벌크 수정 쿼리 em.flush() 질문입니다. 변지수 10일 전
안녕하세요, 좋은 강의 만들어주셔서 감사합니다. 강의듣다가 궁금한것이 생겨 질문드립니다. em.flush() 전에 벌크 수정쿼리를 날려 db에는 41살, 1차캐시에는 40살인데 em.flush()를 하면 db가 40살로 바뀌는게 아닌가요? 결과값이 41로 나온걸로 봐서는  제 생각에는 1차 캐시에 변경이 없기 때문에 flush해도 쿼리가 안나가건가 싶습니다. 명확하게 와닿지 않아 질문드립니다. 감사합니다.

1
kepha 프로필

fetch join 시 child table 조건이 실제 쿼리에 반영이 안되네요.. kepha 13일 전
[LneQuest] @Entity(name = "LneQuest") @Table(name = "lne_quests") @Cacheable @JsonInclude(JsonInclude.Include.NON_NULL) //@NamedEntityGraph(name = "LneQuest.all", attributeNodes = [NamedAttributeNode("quizList")]) class LneQuest (     var type: String,     var title: String,     var description: String?,     @Column(name = "user_constraints")     var userConstraints: String = "{}",     @Column(name = "reward_total")     var rewardTotal: Double,     @Column(name = "reward_remain")     var rewardRemain: Double,     @Column(name = "reward_amount")     var rewardAmount: Double,     @Column(name = "reward_currency")     var rewardCurrency: String,     @Column(name = "thumbnail_url")     var thumbnailUrl: String,     @Column(name = "start_at")     var startAt: LocalDateTime,     @Column(name = "end_at")     var endAt: LocalDateTime,     @Column(name = "deleted_at")     var deletedAt: LocalDateTime? = null,     @OneToMany(fetch = FetchType.LAZY, mappedBy = "quest" /* , cascade = [CascadeType.ALL] */)     var quizList: MutableList<LneQuiz> = mutableListOf() ): AbstractJpaPersistable1() {     // 연관관계 추가 method 는 만들어 놓는게 편리하다.     fun addQuiz(quizz: LneQuiz) {         quizz.quest = this         quizList.add(quizz)     } } @Entity(name = "LneQuiz") @Table(name = "lne_quizzes") @Cacheable @JsonInclude(JsonInclude.Include.NON_NULL) open class LneQuiz(     @JsonIgnore     @ManyToOne(fetch = FetchType.LAZY)     @JoinColumn(name = "quest_id")     var  quest: LneQuest,     var  type: String,     var  title: String,     var  description: String? = null,     var  answers: String? = null,     @Column(name = "correct_answer")     var  correctAnswer: String,     @Column(name = "deleted_at")     var  deletedAt: LocalDateTime? = null ): AbstractJpaPersistable() { } @Query("select q " +             " from LneQuest q INNER JOIN FETCH LneQuiz qz where 1=1 " +             " and (:type is null or qz.type = :type) " +             " and (:from is null or :from < q.createdAt) " +             " and (:to is null or q.createdAt < :to)", nativeQuery = false)     fun findAllByJpql(@Param("type")type: String?,                       @Param("from")from: LocalDateTime?,                       @Param("to")to: LocalDateTime?, pageable: Pageable): Page<LneQuest>                         페치 조인하니까 N+1 문제가 없이 쿼리 1번만 가는데요           조인되는 Child 테이블 컬럼 조건이 반영이 안되네요...;;;           qz.type = :type  Child 테이블 컬럼 조건을 넣어도 페치 조인 쿼리의 경우 Main 테이블 조건으로 들어가네요... 컬럼명이 같은게 있어서 그런건지요???                        SELECT lnequest0_.id               AS id1_0_0_,         quizlist1_.id               AS id1_1_1_,         lnequest0_.created_at       AS created_2_0_0_,         lnequest0_.updated_at       AS updated_3_0_0_,         lnequest0_.deleted_at       AS deleted_4_0_0_,         lnequest0_.description      AS descript5_0_0_,         lnequest0_.end_at           AS end_at6_0_0_,         lnequest0_.reward_amount    AS reward_a7_0_0_,         lnequest0_.reward_currency  AS reward_c8_0_0_,         lnequest0_.reward_remain    AS reward_r9_0_0_,         lnequest0_.reward_total     AS reward_10_0_0_,         lnequest0_.start_at         AS start_a11_0_0_,         lnequest0_.thumbnail_url    AS thumbna12_0_0_,         lnequest0_.title            AS title13_0_0_,         lnequest0_.type             AS type14_0_0_,         lnequest0_.user_constraints AS user_co15_0_0_,         quizlist1_.created_at       AS created_2_1_1_,         quizlist1_.updated_at       AS updated_3_1_1_,         quizlist1_.answers          AS answers4_1_1_,         quizlist1_.correct_answer   AS correct_5_1_1_,         quizlist1_.deleted_at       AS deleted_6_1_1_,         quizlist1_.description      AS descript7_1_1_,         quizlist1_.quest_id         AS quest_i10_1_1_,         quizlist1_.title            AS title8_1_1_,         quizlist1_.type             AS type9_1_1_,         quizlist1_.quest_id         AS quest_i10_1_0__,         quizlist1_.id               AS id1_1_0__  FROM   korbit.lne_quests lnequest0_         LEFT OUTER JOIN korbit.lne_quizzes quizlist1_                      ON lnequest0_.id = quizlist1_.quest_id  WHERE  lnequest0_.type = 'multiple-choice'         AND ( lnequest0_.created_at BETWEEN '2019-03-10T02:00:00.000+0000' AND                                                 '2020-03-10T02:00:00.000+0000' );  

6
진형은 프로필

복합키 맵핑에 대해 질문드립니다 진형은 1달 전
안녕하세요 권영한님 강의 너무 재미있게 잘 보고 있습니다! 😁 복합키 맵핑을 찾아보니 여러방법들이 있더라구요~ 영한님은 복합키 맵핑을 어떤 방법을 사용하시는지 질문 남깁니다.

1
jinwoo sim 프로필

MemberRepository 클래스 생성시 에러 jinwoo sim 1달 전
repository를 만들어서 MemberRepository 인터페이스를 만들었을 때 No bean named 'entityManagerFactory' available가 뜨네요... @EnableJpaRepositories(basePackages = "com.inf.learn.repository") 라고 설정도 했는데,,, 무슨 오류인지 잘 모르겠어요 컨트롤러단 에서는 entityManagerFactory를 만들고 있는데,,,왜 오류가 나는지 혹시 아실까요..?

2
GPK 프로필

JpaRepository 사용시 Exception Handling GPK 1달 전
JpaRepository를 사용하는 경우, org.springframework.dao.DataAccessException은 RuntimeException을 상속해서 하위 Exception들은 모두 try-catch를 하지 않아도 compile상에는 문제가 없게 되버리는데요, API doc상에서 명시적으로 어떤 DataAccessException이 발생할지 기술되지 않아서  코딩하면서 exception handing에서 실수할 여지가 많아 보입니다. 일일히 개발자 스스로 발생 가능한 exception 찾아서 handling해야할지... 좀더 효율적인 방법이 있을까요? 가령, JpaRepository의 deleteById를 사용하는 경우 존재하지 않는 Id이면 EmptyResultDataAccessException이 발생하게 되는데, 이런 경우는 existById로 한번 체크하고 그냥 deleteById를 하는게 바람직한지 아니면 그냥 deleteById를 하면서 try-catch로 발생가능한 DataAccessException 종류를 다 잡아야하는지 애매하네요.

1
김태정 프로필

@Query(""), 따옴표 내 경로표헌식 오류. 김태정 1달 전
영한님의 강의를 따라가다 Query 어노테이션 부분에서 위와같이 강의에서와 달리 경로 표헌식이 먹히질 않습니다. 그래서 일일이 다 수기 작성을 하는 중인데, 구글에 검색을 해봐도 이런 오류에 대해서 언급한 곳이 없더라고요.. 해결 방법이 있을까요?  (sdk 1.8,  intelliJ 19.02  windows 유저입니다.)

3
Junyoung_Choi 프로필

Unable to access lob stream 오류가 발생합니다. Junyoung_Choi 1달 전
다음과 같이 AccountRepository 인터페이스를 생성해 사용하는데, findByNickname 메소드에 대해 Unable to access lob stream 오류가 발생합니다. 검색해보니 맨 위 사진과 같이 Repository에 @Transactional을 추가하라는데, Clob이나 Blob이 포함된 엔티티는 해당 어노테이션을 반드시 사용해야 하는 것인가요? 혹시 맞다면 왜 그런건가요?

3
익명 프로필

낙관적 락 사용방법에 대한 질문 익명 1달 전
안녕하세요. 실무에서 비관적 락을 사용하던 것을 낙관적 락으로 변경하고자 하는데 잘 안되는 부분이 있어서 한참을 헤매다가 질문을 올립니다. 1. 기존에 version 필드가 없던 테이블에서 새로 version 필드를 추가할 때 ddl 을 어떻게 구성해야 할까요? alter table TABLE add version int default 1 not null; 이런식으로 default 값 1 에 not null 조건을 주어서 기존 데이터들의 버전을 1로 임의로 고정해놨는데요. 만약 기존 데이터의 마그레이션이 필요 없이 테이블을 새로 생성하는 상황 이라고 한다면 not null 이나 default 조건을 안줘도 jpa가 알아서 처음부터 insert 할때 version 1부터 잘 들어가나요? 2. 엔티티에 @Version 을 추가해서 NONE 모드의 낙관적인 락은 잘 동작하는것을 확인했는데요. 그런데 추가적인 옵션을 주고 싶어서 책에 언급된 Optimistic 를 이런식으로 조회에 추가해서 사용해 보았는데요. @Lock(LockModeType.OPTIMISTIC)Optional<Table> findById(Long id); 조회까지는 잘 되는데 문제는 가져온 이 엔티티에 변경이 이뤄질 때 무조건 다음과 같은 알 수 없는 에러가 발생합니다. 당연히 version 컬럼은 테이블에 잘 추가되어 있습니다. 다음은 문제가 발생할떄의 로그입니다. OPTIMISTIC 모드 이렇게 사용하는게 아닌건지.. Hibernate:      select         `version`      from         `TABLE`      where         `id` =? 2020-06-03 13:20:06.595  WARN [,,,] 1888 --- [    Test worker] o.h.engine.jdbc.spi.SqlExceptionHelper   : SQL Error: 0, SQLState: S0022 2020-06-03 13:20:06.596 ERROR [,,,] 1888 --- [    Test worker] o.h.engine.jdbc.spi.SqlExceptionHelper   : Column '`version`' not found. 3. 엔티티에 @Version 을 붙이면 기본적으로 그 엔티티가 낙관적인 락에 의해 수정시에 version 정보를 비교하는 로직이 추가된다고 이해를 했습니다. 그런데 특정 쿼리에 @Lock(LockModeType.OPTIMISTIC) 을 붙여주는 것은 그 쿼리를 통해 가져온 엔티티에만 추가적인 락 로직이 들어가고 만약 @Lock 이 안붙은 또다른 쿼리가 있다고 가정하고 그 쿼리도 실제 결과는 같은 엔티티를 내려준다고 했을때 후자의 쿼리로 가져온 엔티티는 NONE 모드 락만 적용되는 것이 맞을까요?

1
Jung Cheol 프로필

도메인/DTO에 대해 질문드립니다. Jung Cheol 1달 전
반드시 DTO를 사용하라고 하셨는데. 하나의 도메인에 여러 개의 연관관계와 여러 개의 조회용 API가 있고, 각각 API에서 사용하는 연관관계가 다른 경우의 조언을 구하고 싶습니다. Ex) Member에 Region, Team 연관관계가 있고, 1번 API에서는 Region을, 2번 API에서는 Team을 fetch join 이런 상황에서 작업을 하다가 DTO 변환이나 쿼리 관련 에러가 발생하거나 API 스펙이 기억나질 않으면 '(1) 서비스 -> 도메인 확인 (2) DTO -> 도메인 확인 (3) Repository 쿼리 확인 -> fetch 대상 확인' 와 같은 복잡한 과정을 거치게 되네요. 이를 메소드명이나 클래스명으로 표현하기에 적합한 방법이 있을까요?

1
LUA 프로필

테스트 공부를 위한 방법을 알 수 있을까요 LUA 1달 전
늘 빛영한 님의 명강의 즐겁게 보고있습니다. 이동욱님의 도서와 영한님의 강의를 보며 테스트코드를 접하면서 대략적인 느낌으로 어떤역할을 하는지 왜 작성하는지를 미약하게나마 느끼고있지만 테스트코드에 대해 모르는 부분이 너무나 많은데요 테스트코드는 거의 필수처럼 여겨지는것으로 보이던데 테스트코드를 학습하기위해 혹시 추천해주고 싶은 책이나 그 외 자료 같은게 있으실지 궁금합니다!

1
지식공유자 되기
많은 사람들에게 배움의 기회를 주고,
경제적 보상을 받아보세요.
지식공유참여
기업 교육을 위한 인프런
“인프런 비즈니스” 를 통해 모든 팀원이 인프런의 강의들을
자유롭게 학습하는 환경을 제공하세요.
인프런 비즈니스