일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |
- MySQL
- 동시성
- java
- 동시성 문제
- MVCC
- jpa
- Locking Read
- gc
- iterable
- Atomic Type
- foreach
- iterator
- 가비지 컬렉션
- 백엔드
- 스프링
- db
- Varchar
- 가비지 컬렉터
- Synchronized
- text
- reflection
- CAS
- Di
- Lock
- 자바
- 데이터 타입
- Today
- Total
목록전체 글 (98)
과정을 즐기자

웹툰 만들기 토이 프로젝트를 진행하면서 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에서도 지연로딩으로 데이터를 가져올 수 있습니다. 이렇게 편리한 것 같지만 치명적인 단..
테스트 코드에서 @Transactional은 데이터베이스도 롤백이 되기 때문에 @BeforeEach에서 일일이 repository를 deleteAll 해주지 않고 외래키 문제로 고민할 필요도 없기 때문에 편리합니다.그래서 자주 사용을 했었는데 한가지 문제점이 있습니다. 바로 원래 코드에서 @Transactional이 없더라도 테스트 코드에서 @Transactional을 사용한다면 하나의 트랜잭션으로 묶여 원래 코드와 다른 결과를 나타낼 수 있다는 점입니다. 이 문제점은 예전 글에서 작성한 적이 있습니다. JPA 변경감지 적용이 안될 때JPA 변경 감지 적용이 안된다? 프로젝트에서 리뷰 수정 기능을 구현하고 있는데 JPA에서는 변경 감지(더티 체킹)를 작동한다는 사실을 알고 있었다. 영속성이 유지되는 ..
이번 글에서는 요청과 응답에서 엔티티를 직접 사용하면 안되는 이유에 대해서 작성해보려고 합니다. 일단.. 너무 기계적으로 dto를 사용했기 때문에 왜 dto가 필요한지를 생각해보려고 합니다. @Override public void save(Member member) { memberJpaRepository.save(member); } 먼저 스프링 데이터 JPA를 사용한 Member의 회원 가입을 예시로 들어서 설명하겠습니다. 위와 같이 Member 엔티티를 저장할 수 있습니다. repository에서 save를 할 때는 엔티티를 직접 사용하지만 회원 가입을 위해 회원이 입력한 데이터를 controller에서 받고.. service 계층을 거쳐 repository까지 엔티티를 전달하는 방식은 바람직한 방식은..

이번 글에서는 자체적으로 만든 로그인과 소셜 로그인을 같이 사용했던 방법에 대해서 정리하고자 합니다. 먼저 자체적으로 만든 로그인부터 살펴보겠습니다. 자체 로그인 구현 회원가입 입력한 정보를 바탕으로 DB에 저장하였습니다. 이때 비밀번호는 그대로 저장하면 보안상 문제가 되기 때문에 BCyptPasswordEncoder를 사용하여 암호화 했습니다. @Configuration public class SecurityConfig { @Bean public PasswordEncoder passwordEncoder(){ return new BCryptPasswordEncoder(); } ... } 로그인, 로그아웃 먼저 입력한 정보가 DB에 있는 회원 정보와 일치하는지 확인한 후 로그인을 진행하는데 로그인을 유지하..

문제 상황 웹툰 서비스 프로젝트에서 코인을 지불하면 미리 보기 기능을 이용할 수 있도록 구현하고 있었다. 이때 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..
컨트롤러, 서비스, 도메인 각 계층이 가지고 있어야 할 코드에 대해 고민한 내용을 정리하고자 한다. 먼저 어떻게 왜 고민을 하게되었는지 배경부터 말해보면 프로젝트를 진행하면서 만화를 수정할 수 있도록 기능을 추가하려고 하였다. 만화를 수정하려면 먼저 작가로 로그인한 상태에서 만화의 id와 변경할 정보를 CartoonUpdate로 전달해줘야 한다. 겪은 문제점 Controller @PatchMapping("/cartoon/{cartoonId}") public ResponseEntity update(@LoginForAuthor AuthorSession authorSession, @PathVariable Long cartoonId, @RequestBody @Valid CartoonUpdate cartoonUp..
웹툰 서비스를 만드는 프로젝트를 진행하면서 테스트 코드 작성시 로그인 인증이 필요한 경우가 생겼다. 우선 배경부터 설명하자면 일반 회원이 아닌 작가로 로그인 한 경우에만 만화를 등록할 수 있다. 이때 @LoginForAuthor을 만들었고 ArgumentResolver로 로그인 한 작가인지를 확인하였다. CartoonController @RequiredArgsConstructor @RestController public class CartoonController { private final CartoonService cartoonService; @PostMapping("/cartoon") public ResponseEntity save(@LoginForAuthor AuthorSession authorSe..

로그인 방식 개선 과정 프로젝트를 진행하면서 저번보다 로그인 방식을 조금 수정하였다. 먼저 어떻게 개선하였는지 먼저 간략하게 소개하자면 1. 기존에는 HttpSession을 이용하여 톰캣에 세션을 저장하였다. 이 방식은 톰캣을 종료하면 세션 정보가 다 사라지기 때문에 사용자가 처음부터 다시 로그인을 진행해야 하는 문제점이 있었다. 해결책으로 세션을 DB에 저장할 수도 있고 Redis와 같은 인메모리 캐시에 저장할 수 있다. 이번 프로젝트에서는 세션을 DB에 저장하는 방식으로 바꾸었다. (이때 Spring Boot의 설정으로 DB에 저장하는 방식도 있지만 이번에는 세션 엔티티를 직접 구현해서 해봤습니다) 또한 HttpSession을 이용하지 않고 ResponseCookie로 세션에 맞는 쿠키를 설정하였다...

JPA 변경 감지 적용이 안된다? 프로젝트에서 리뷰 수정 기능을 구현하고 있는데 JPA에서는 변경 감지(더티 체킹)를 작동한다는 사실을 알고 있었다. 영속성이 유지되는 엔티티라면 update 쿼리를 따로 날려주지 않고 엔티티의 값을 변경하면 트랜잭션 커밋을 할 때 수정된 내용이 반영된다는 것이다. 이러한 사실을 알고 있었는데 테스트 코드 작성시 변경 감지가 적용이 안되었다. 왜 그럴까..? 우선 Controller, Service, Domain 코드를 살펴보자. ReviewController @RequiredArgsConstructor @RestController public class ReviewController { private final ReviewService reviewService; ... ..