본문 바로가기

FastCampus - 한번에 끝내는 Java|Spring 웹 개발/04 JPA

(28)
JPA Ch 7 영속성 - 트랜젝션 매니저 (5) - 패스트캠퍼스 챌린지 34일차 저번 강의에서 놓친 것도 있고, 딱 5번영상까지가 트랜젝션의 격리수준 내용이라 (피곤하기도 해서) 오늘은 끝까지는 안 가고 다음 강의만 봤습니다. 이전 강의에서 놓친 내용 격리 수준을 저번 강의를 정리할 때 한 번 쭉 정리해서 전부 이해하기는 했는데, 강의에서는 테스트를 위해 격리수준 설명 이외의 몇 가지를 더 소개해주셨더라구요. 최초로 확인해보는 격리 수준은 MySQL의 기본값인 REPEATABLE_READ 입니다. Lv2 격리수준으로, where 절의 조건에 맞는 게 추가되면 다음 where 쿼리에 포함될 수 있는 phantom read 가 일어날 수 있습니다. READ_UNCOMMITED 가 최소 격리 수준 (Lv 0) 으로 더티 리드 부분에서 정리했던 거네요. DB 차원에서 정합성을 지켜주기 위해..
JPA Ch 7 영속성 - 트랜젝션 매니저 (3~4) - 패스트캠퍼스 챌린지 33일차 "심화학습"이 되시겠습니다. 주요 내용은... @Transactional 이 어떻게 동작하는지 (이전 강의 정리할 때 대충 봐서 이미 알죠) 잘못된 @Transactional 의 사용: private 메소드, 같은 클래스의 메소드 @Transactional 의 2가지 속성 학습: isolation, propagation 이 되시겠습니다. @Transactional 의 동작 방식: AOP 사용 이전 강의를 정리하면서 봤던 그림(강의에는 없었고 공식 문서였음)에 해당하는 내용을 소스를 까보면서 살펴봅니다. 출처야 당연히 공식문서구요. TransactionAspectSupport 라는 클래스를 찾아갑니다. 호출시에 디버그 브레이크를 잡아보면 확인할 수 있어요. 콜스택에 있습니다. invokeWithTransa..
JPA Ch 7 영속성 - 트랜젝션 - 패스트캠퍼스 챌린지 32일차 드디어... 며칠만에... 좀 편한 강의에 도달했다... 이번 강의 시리즈 자체는 좀 깁니다. 그런데 앞에 두 개만 봐서 양이 좀 적나보네요. "트랜젝션 매니저" 강의 시리즈에서는 이전부터 설명은 않고 계속 써오던 @Transactional 과 트랜젝션, 그리고 그걸 관리하는 트랜젝션 매니저에 대해서 다룹니다. 강의 하나가 길어서 그냥 n조각된 거 같아보이네요. 그래서 두 개 봤습니다. [ 그러면 안 데 캘리코 짤 (을 상상해주세요) ] 트랜젝션 트랜젝션은 DB의 개념입니다. 아시다시피요. @Transactional 이 있는 범위가 트랜젝션의 시작과 끝입니다. 중첩되면 어떻게 되는지도 이미 아시죠? 트랜젝션은 트랜젝션 매니저가 관리해주는 모양입니다. 아직 강의에서 실체가 나오지는 않았습니다. 트랜젝션의 ..
JPA Ch 7 영속성 - 생명주기 - 패스트캠퍼스 챌린지 31일차 1차 캐시를 경유하는 것에 의한 라이프사이클을 실습으로 확인합니다. 엔티티의 상태 상태는 빠르게 3가지 정도를 언급해주셨습니다. 이것도 출처에 따라 말이 좀 다른 거 같긴 한데... 의미하는 바는 얼추 비슷해보입니다. 용어보다 중요한 건 (1)관리되느냐 (2)언제 반영되느냐 (3)반영되긴 하느냐 정도인 것 같네요. 강의에서는 이런 용어들의 명확한 정의에 대해서 다루지는 않으셨습니다. 그냥 비슷한 용어가 영어로도 이런 종류가 있으니 잘 기억해두라 정도였던 것 같네요. 인터넷을 검색해보면 출처를 알 수 없는 다이어그램들이 많이 나옵니다. 설명도 출처가 같이 명시되지 않은 경우가 많구요. 결국 원류를 찾아 거슬러올라가다보면 Jakarta Persistence (= JPA) 문서를 만나게 됩니다. 그러니까, h..
JPA Ch 7 영속성 - 엔티티 캐시 (1차 캐시) - 패스트캠퍼스 챌린지 30일차 이번엔 SQL 쿼리 로그로 확인해보는 영속성 캐시 이해하기 강의였습니다. 앞선 강의를 공부하는 과정에서 EntityManager의 문서를 굉장히 주의깊게 읽었기 때문에 이해하는 데 크게 어려움이 없었고, 강의에서도 친절하게도 예시를 보여주셔서 실습조차 필요하지 않은 수준이 되었습니다. Entity Manager 직접 써보기 앞서 JPA에서 엔티티의 영속을 다루는 범위인 Persistence Context 를 다루는 인터페이스는 interface EntityManager 라는 것을 살펴봤습니다. 먼저 이걸 테스트에서 직접 불러와서 사용해봅니다. @SpringBootTest 안에서는 EntityManager 를 @Autowire 로 DI받아 끌어올 수 있습니다. @SpringBootTest @Transact..
JPA Ch 7 영속성 - 개요 & 리얼 DB - 패스트캠퍼스 챌린지 29일차 한 개 강의가 48분에 육박하는 긴 강의라 2배속으로 봐도 시간소요가 컸습니다. 중간중간 일시정지한 것도 있구요. 4배속 진짜 필요하다니까... 오늘 강의의 주된 내용은 두 가지입니다. JPA 를 깊게 이해하기 위한 개념설명: "Persistence Context" 의 개념만 가볍게 (Spring Boot를 쓰면 이 짓을 수동으로 할 필요가 없으니까) H2 에서 리얼 디비로 변경 (MySQL) & 트러블슈팅 및 추가 설명 Persistence Context (영속맥락?) 여기에서는 다음 강의부터 자세하게 배울 개념적인 부분을 살짝 공부하고 넘어갑니다. Persistence Context가 뭔데? 강의에서 설명은 "Spring이 Bean을 관리하는 것처럼" 이라는 비유 방식이었습니다. JPA에서 DB/파일..
JPA Ch 6 릴레이션 M:N - 패스트캠퍼스 챌린지 28일차 남은 건 M:N 이죠. 이번엔 실습을 할 필요조차 없었습니다. 몇 가지만 기억하면 됩니다. @ManyToMany 예상하시는 대로 @ManyToMany 를 선언해주면 됩니다. 서로 M:N 으로 참조할 두 개의 엔티티에 정의해주시면 되구요, 리스트 타입으로 정의하고 초기화를 해준다 정도면 되겠습니다. 이전 강의에서 배웠던 @OneToMany 와 사용방법에 있어서는 차이가 없습니다. 다만 중요한 건 이번에는 매핑 테이블이 생긴다는 점입니다. 강의에서는 Book 과 Author 간의 관계로 실습을 진행했는데 author_books 라는 테이블이 생겼습니다. 두 개의 테이블만으로는 M:N 관계를 나타낼 수 없으니 당연한 거겠죠. 아직 영속성을 배우지 않았으므로 오류가 나는데, 이의 해결방법으로 @Transacti..
JPA Ch 6 릴레이션 1:N, N:1 - 패스트캠퍼스 챌린지 27일차 이번에는 1:N, N:1 관계를 봅니다. 이전에 이어서 생각해보자면, 이전의 어노테이션이 @OneToOne 이었으니까 이번엔 @OneToMany, @ManyToOne 이겠죠. 다만, 이번에는 나중에 배운다고 넘어간 좀 석연찮은 부분들이 있습니다. 특히 트랜젝션 관련 부분인데 관련해서 설명을 미루다보니 좀 이해가 안 가는 오류를 맞닥뜨릴 수 밖에 없었습니다. 영속성 얘기하면서 뭐 나오겠죠. 그래서 이번엔 답답해서 잠깐 쉬기도 하고, 결국 그냥 가벼운 마음으로 진행하기로 했습니다. @OneToMany 이전에 만들었던 User와 UserHistory 의 관계를 @OneToMany 와 @ManyToOne 을 사용하는 것으로 바꿉니다. 먼저 @OneToMany 입니다. 앞부분의 "One"이 이 객체(User)이고..
JPA Ch 6 릴레이션, ERD, 1:1 - 패스트캠퍼스 챌린지 26일차 DB 하면 릴레이션을 빼놓을 수 없습니다. 이번 섹션에서는 ERD를 먼저 그리고, 거기에 맞춰 Spring Data JPA / Jakarta Persistence 가 제공해주는 릴레이션 기능을 사용해봅니다. Entity-Relation Diagram 대학의 DB 시간에 배웠던 내용들입니다. 지금은 책이 본가에 있어서 정확한 그리기 방식을 다시 확인해보기가 어렵네요... 강의에서는 아무래도 간이 형식으로 진행한 것 같습니다. ---+[엔티티] : 1개 ---|
JPA Ch 5 Entity Listener (2) - 패스트캠퍼스 챌린지 25일차 EntityListener의 두 번째 강의입니다. 실습 위주라 필기할 내용은 생각보다 많지 않았고, 새로운 내용이 좀 있습니다. 덕분에 필기하는 시간보다 실습하고 찾아보는 시간이 더 기네요. UserHistory 를 만들어보자 User가 변경되었을 때 마지막으로 변경한 시간을 남기는 것도 좋지만, 변경 내역이 별도의 테이블에 들어있으면 나중에 확인하기 더 수월합니다. 그래서 UserHistory 를 만듭니다. 방법은 EntityListener를 만드는 것까지는 똑같습니다. EntityListener 를 만드는 시점에서 좀 달라집니다. 히스토리 엔티티 생략 public class UserHistory { @Id @GeneratedValue private Long id; private Long userId;..