일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | |||||
3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 |
- Locking Read
- iterator
- Varchar
- 백엔드
- java
- Synchronized
- db
- Di
- 자바
- MySQL
- jpa
- Lock
- CAS
- foreach
- MVCC
- 가비지 컬렉션
- gc
- reflection
- iterable
- Atomic Type
- 스프링
- text
- 동시성
- 동시성 문제
- 데이터 타입
- 가비지 컬렉터
- Today
- Total
목록Spring Data (14)
과정을 즐기자
프로젝트를 진행하면서 사용자가 시간표를 등록하면 해당 시간표 정보를 서비스의 캘린더에 반영하는 기능을 구현하였습니다.이때 1명의 사용자만 한 학기의 시간표를 등록해도 한 번에 200, 300개의 insert 쿼리가 날라갔습니다.만약 1000명의 사용자가 동시에 등록을 하게되면 20, 30만건의 insert 쿼리가 한 번에 날라가게 된 것입니다.📕 Spring Data JPA의 save() 메소드기존에 Spring Data JPA를 사용하여 단순히 save 메소드를 호출하였는데 서비스가 점점 커질수록 이러한 방식은문제점을 가지고 있던 것입니다. 먼저 기존의 코드를 살펴보겠습니다. 저장할 스케줄을 List로 받아서 하나 하나 save 메소드를 호출해주었습니다. @Transactional public voi..
마주친 문제 예전에 했던 프로젝트(웹툰)에서 양방향 매핑을 사용하였습니다. 양방향 매핑을 사용하는 이유는 도메인 로직을 풀어낼 때 개발의 편의성이 크고 객체 지향적인 설계를 유지할 수 있기 때문입니다. 그래서 저도 양방향 매핑을 사용했지만 서로 순환 참조를 한다는 문제점이 있습니다. 이러한 점을 고려했을 때 어떠한 설계가 더 나은지 이야기 해보겠습니다. 양방향 매핑을 사용 먼저 양방향 매핑을 사용한 예시를 확인 해보겠습니다. 웹툰 서비스에서 작가(Author), 만화(Cartoon)가 OneToMany 양방향 매핑입니다. Author @Getter @NoArgsConstructor(access = PROTECTED) @Entity public class Author extends BaseTimeEntit..
웹툰 만들기 토이 프로젝트를 진행하면서 Spring Data JPA, QueryDsl을 사용하여 여러 조회 기능을 구현하였습니다. 이번 글에서는 여러 구현한 부분 중 대표적인 사례 4개를 작성해보려고 합니다. 1. ManyToOne에서 EntityGraph 사용하여 엔티티 조회 구현한 기능은 만화 제목을 검색하면 검색어를 포함한 모든 만화를 페이징 처리해서 가져오는 것입니다. 우선 Cartoon과 Author는 ManyToOne 양방향 매핑 관계입니다. Author @Getter @NoArgsConstructor(access = PROTECTED) @Entity public class Author extends BaseTimeEntity { ... @OneToMany(mappedBy = "author",..
OSIV란 Open-Session-In-View 의 약자로 영속성 컨텍스트를 뷰까지 열어두는 기능을 말합니다. 스프링부트를 사용하면 기본적으로 OSIV 설정이 true입니다. 설정을 어떻게 하느냐에 따라서 각 계층에서 영속 상태인지 아닌지가 달라지기 때문에 주의하여 사용해야 합니다. 이번 글에서는 OSIV 설정을 false로 변경하면서 코드를 어떠한 방식으로 리팩토링 하였는지에 대해서 작성해보려고 합니다. OSIV true OSIV 설정이 true이면 영속상태를 뷰까지 열어두기 때문에 코드를 작성하기 편리합니다. 계층이 달라지더라도 동일성이 보장되기 때문에 같은 엔티티 인스턴스를 반환할 수 있습니다. Controller에서도 지연로딩으로 데이터를 가져올 수 있습니다. 이렇게 편리한 것 같지만 치명적인 단..
문제 상황 웹툰 서비스 프로젝트에서 코인을 지불하면 미리 보기 기능을 이용할 수 있도록 구현하고 있었다. 이때 Internal Server Error 500, ByteBuddyInterceptor Type defnition error가 발생하였다. DB에는 회원의 코인 지불이 반영되었는데 만화정보를 json으로 반환하지 못하였다. 문제의 원인 우선 엔티티의 구조부터 살펴보자 Content @Getter @NoArgsConstructor @Entity public class Content extends BaseTimeEntity { ... @ManyToOne(fetch = LAZY) @JoinColumn(name = "cartoon_id") private Cartoon cartoon; ... } Carto..
JPA 변경 감지 적용이 안된다? 프로젝트에서 리뷰 수정 기능을 구현하고 있는데 JPA에서는 변경 감지(더티 체킹)를 작동한다는 사실을 알고 있었다. 영속성이 유지되는 엔티티라면 update 쿼리를 따로 날려주지 않고 엔티티의 값을 변경하면 트랜잭션 커밋을 할 때 수정된 내용이 반영된다는 것이다. 이러한 사실을 알고 있었는데 테스트 코드 작성시 변경 감지가 적용이 안되었다. 왜 그럴까..? 우선 Controller, Service, Domain 코드를 살펴보자. ReviewController @RequiredArgsConstructor @RestController public class ReviewController { private final ReviewService reviewService; ... ..
JPA의 데이터 타입 JPA의 데이터 타입을 가장 크게 분류하면 엔티티 타입과 값 타입으로 나눌 수 있다. 엔티티 타입의 특징 식별자(@Id)가 있어 식별자로 구분할 수 있다. 생성하고 영속화하고 소멸하는 생명주기가 있다. 어떤 한 엔티티가 다른 엔티티에서 얼마든지 참조될 수 있다. 즉 참조 값을 공유할 수 있다. 값 타입의 특징 식별자가 없다 생명 주기가 엔티티에 의존한다. 오직 하나의 주인만이 관리하게 해야하며 불변 객체로 만들고 공유하지 않는 것이 안전하다. 이제 값 타입에 대해서 더 자세히 알아보자 값 타입 값 타입은 3가지로 나눌 수 있다. 기본 값 타입 임베디드 타입 컬렉션 값 타입 기본 값 타입 기본 값 타입에는 자바 기본 타입, 래퍼 클래스, String이 있다. 이들은 위에서 말한 것 처..
프록시 엔티티를 조회할 때 연관된 엔티티들이 항상 사용되는 것은 아니다. Member와 Team 엔티티가 있을 때 필요한 정보는 Member인데 Member를 조회할 때 Team까지 데이터베이스에서 함께 조회하는 것은 효율적이지 않다. 따라서 Team 엔티티 값을 실제 사용하는 시점에 데이터베이스에서 조회하는 방법이 필요하다. 그 방법이 지연로딩이다. 이러한 지연 로딩 기능을 사용하려면 데이터베이스 조회를 지연할 수 있는 가짜 객체가 필요하고 이것을 프록시 객체라고 한다. Member member = em.find(Member.class, "member");위와 같이 엔티티를 직접 조회하면 조회한 엔티티를 실제 사용하든 사용하지 않든 데이터베이스를 조회하게 된다. Member member = em.get..
상속 관계 매핑 관계형 데이터베이스에는 객체지향 언어에서 다루는 상속이라는 개념이 없다. 대신 슈퍼타입 서브타입 관계라는 모델링 기법이 객체의 상속 개념과 가장 유사하다. ORM에서 이야기하는 상속 관계 매핑은 객체의 상속 구조와 데이터베이스의 슈퍼타입 서브타입 관계를 매핑하는 것이다. 슈퍼타입 서브타입 논리 모델을 실제 물리 모델인 테이블로 구현하는 방법에는 3가지가 있다. 각각의 테이블로 변환하는 조인 전략 통합 테이블로 변환하는 단일 테이블 전략 서브타입 테이블로 변환하는 구현 클래스마다 테이블 전략 밑에서 설명할 예시에는 모두 Item 클래스를 부모 클래스로 만들고 Album, Movie, Book을 자식 클래스로 만들었다고 하자. 조인 전략 엔티티 각각을 모두 테이블로 만들고 자식 테이블이 부모..
다대일 데이터베이스 테이블에서 일, 다 관계에서 외래 키는 항상 다쪽에 있다. 객체에서도 마찬가지로 연관관계의 주인이 다쪽으로 하면 다대일 관계이다. 예를들어 주문(order), 회원(member)가 있다고 하자. 한 회원이 여러 주문을 할 수 있다고 하면 주문과 회원은 다대일 관계이다. 이때 외래 키는 다쪽인 주문이 가지고 있다. 따라서 양방향 매핑에서 연관관계의 주인은 order이다. @ManyToOne @JoinColumn(name = "member_id") private Member member;위와 같이 단방향 매핑을 완성할 수 있다. @OneToMany(mappedBy = "member") private List orders = new ArrayList();이렇게 mappedBy를 이용하여 양..