분류 전체보기
[JPA] @OneToMany 단방향을 사용하면 안되는 이유
[JPA] @ManyToOne, @OneToMany 뭘 써야할까? 편에서 단방향, 양방향 맵핑에 대해서 다뤘었죠! 그리고 분명 단방향만으로 충분한 경우에는 굳이 양방향 맵핑을 안하는게 좋다고도 했는데... 사실 단방향 중에 @OneToMany 맵핑으로만 이루어진 단방향 맵핑은 사용하지 않는게 좋습니다. 뭐야?!? 단방향 쓰라더니 왜 또 쓰지 말라는거야 ㅡㅡ 라고 하실 수도 있지만.. 여기에는 당연히 이유가 있습니다. 어떤 문제가 있는지, 해결방법은 없는지 지금부터 한번 알아보겠습니다! @OneToMany 단방향 세팅 우선 Classroom, Student로 @OneToMany 단방향 맵핑을 구현해보겠습니다. // Classroom 엔티티 @NoArgsConstructor @Getter @Entity pu..
[JPA] @ManyToOne, @OneToMany 뭘 써야할까?
전에 Spring Data JPA를 사용할 때의 N+1문제를 다루면서 연관관계 엔티티에 대해서 이야기를 했었습니다! JPA에서는 A엔티티, B엔티티 연관성(1:1, N:1, N:N)을 명시해주면, 연관된 엔티티를 저장하거나 조회하는 것이 가능합니다. 대표적으로 다음의 어노테이션을 쓸 수 있죠! @OneToOne (1:1) @OneToMany (1:N) @ManyToOne (N:1) @ManyToMany (N:N) 우선 그럼 오늘의 주인공인 일대다 연관성을 나타내는 @OneToMany, @ManyToOne 어노테이션부터 알아볼까요? @OneToMany, @ManyToOne 예제 교실과 학생 예제를 통해서 나타내보겠습니다. 보통 하나의 교실에 여러명의 학생이 속해있겠죠! Tip) @OneToMany, @Ma..
[Redis] Redis란?
Redis란 인메모리(in-memory) 데이터 구조를 가진 저장소입니다. 네 Redis는 디스크(Disk)가 아니라 메모리(RAM)에 모든 데이터를 저장하고 조회합니다! 일반 RDB말고 인메모리 데이터 구조 저장소를 사용하는 이유는 뭔가요?? 일반적으로 RDB는 데이터를 물리적으로 디스크에 직접 쓰는 형식입니다. 이로인해 데이터가 서버에 문제가 생겨도 데이터가 직접적으로 손상이 되지 않는다는 장점이 있지만, 읽고 쓰는 과정이 메모리에서 불러오는 것에 비해 훨씬 느립니다. 따라서 빠르게 데이터를 읽고 쓰는 캐시 서버로 사용하기 위해 Redis를 사용합니다. 캐시는 한번 읽어온 데이터를 임의의 공간에 저장하여 다음에 읽을 때는 빠르게 결괏값을 받을 수 있도록 도와주는 공간입니다. 같은 요청이 여러 번 들어..
[Spring Boot] @Transactional 어노테이션 속성
[JPA] 영속성 컨텍스트(Persistence Context)란? 편에서 자주 등장했던 단어 트랜잭션(Transaction)이 있습니다. Spring Boot 에서는 @Transactional 어노테이션을 통해 해당 메소드가 하나의 트랜잭션으로 묶여있다는걸 명시하는데요! 이 @Transactional 어노테이션에는 개발자가 커스텀할 수 있는 여러가지 옵션이 있습니다. 한번 살펴볼까요? Propagation 옵션 이벤트 버블링과 캡쳐링 편에서도 등장했던 Propagation이라는 단어가 다시 등장했습니다. 바로 브랜드 E 스킬처럼 전파라는 의미를 가지고 있는데요. @Transactional을 쓸 때, 스프링은 트랜잭션의 시작과 중지를 propagation 세팅을 바탕으로 관리하는데요, 이 Propagat..
[JPA] OneToMany(1:N) 페이징 처리
지금까지 연관 엔티티를 불러오기 위해 지연로딩과 즉시로딩 방법을 알아보았고, N+1 문제를 해결하기 위해 fetch join을 사용하는 것과 이 fetch join을 쉽게 적용할 수 있는 @EntityGraph에 대해서도 알아보았습니다. 하지만 마지막 하나 남아있는게 있습니다. DB 테이블에는 얼마나 많은 양의 정보가 있는지 모르기때문에, 특정 조건으로 데이터 리스트를 조회할때 보통 페이징 처리를 합니다. 그런데 이 연관 엔티티를 페이징 처리하려면 어떻게 해야할까요?? 보통 페이징 처리를 할때 저희는 PageRequest 객체를 만들어서 파라미터로 넘깁니다. public interface OrderRepository extends JpaRepository { Page findOrderWithOrderPr..
[JPA] @EntityGraph 란?
[JPA] 일반 Join과 Fetch Join의 차이 에서 N+1문제를 해결하기 위해 fetch join을 쓴다는 것을 알 수 있었죠! @EntityGraph는 바로 Spring Data JPA에서 fetch join을 어노테이션으로 사용할 수 있도록 만들어 준 기능입니다! 일반적으로 fetch join을 사용하기 위해서는 아래코드처럼 JPQL을 직접 입력해주어야하는 수고로움이 있습니다. @Query("SELECT distinct t FROM Team t join fetch t.members") public List findAllWithMemberUsingFetchJoin(); 하지만 @EntityGraph를 사용하면 이렇게 간편하게 바뀔 수 있습니다 :)) @Override //기본 적으로 findAl..
[JPA] 일반 Join과 Fetch Join의 차이
Spring Data JPA(이하 줄여서 JPA)를 사용하다보면 연관 관계 맵핑이 된 엔티티를 사용하면서 N+1의 문제를 마주하고는 합니다. 예를 들어 우리가 보통 DB에서 연관 맵핑 관계를 볼때는 join 문을 사용해서 쿼리를 만들지만 이상하게 JPA repository로 엔티티를 호출하면 연관된 맵핑만큼 select 쿼리가 만들어집니다 바로 N+1번 쿼리가 진행되는것이죠. 이때 보통 아래 코드처럼 fetch join 이 들어간 JPQL 코드를 작성해서 문제를 해결합니다 @Query("SELECT distinct t FROM Team t join fetch t.members") public List findAllWithMemberUsingFetchJoin(); 왜 일반 join으로는 해결을 못할까요? ..
[JPA] 즉시 로딩(FetchType.EAGER)과 지연 로딩(FetchType.LAZY)
Spring Data JPA (이후 줄여서 JPA)를 사용할때 우리는 엔티티를 영속성 컨테스트에 저장하고 flush 해주는 방식으로 DB에 저장했습니다. 엔티티가 RDB의 테이블과 맵핑된 경우, 모든 테이블이 독립적이지 않아서 필요에 따라 테이블을 join 해서 사용하는 경우가 자주 발생합니다. 이럴 경우 우리는 엔티티에 @OneToOne, @ManyToOne, @OneToMany, @ManyToOne 어노테이션을 이용해서 알려줍니다. 예를 들어 아래 코드를 한번 볼까요? @Getter @Entity public class Classroom { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; private String cl..
[Spring Boot] AutoConfiguration 이란?
AutoConfiguration 즉 자동 환경설정은 스프링부트의 가장 큰 장점 중 하나입니다. 비즈니스 로직을 제외한 많은 부분에서 개발자가 직접 구현하거나 코드를 써야하는 일을 줄여주기 때문입니다. 오늘은 스프링부트의 이러한 자동 설정환경이 어디서부터 어떻게 실행되고, 무엇을 실행시켜주는지 알아봅시다! 스프링 부트(Spring Boot)의 시작 @SpringBootApplication public class Application { public static void main(String[] args) { SpringApplication.run(Application.class, args); } } 스프링 부트 프로젝트를 처음 생성하면 다음과 같은 메인 애플리케이션 클래스를 보실 수 있습니다. main()..
[보안] CORS 란? CORS 에러란?
프론트엔드 개발을 하다보면 무심코 브라우저단에서 백엔드 서버에 요청을하다가 한번쯤 CORS 에러를 마주해보셨을 것 같습니다. 위 사진처럼 console에 뜨게되는데요. 처음 마주하면 아니 나는 정상적으로 요청했는데?! postman으로 호출하면 잘 호출되던데?! 왜 너는 허락을 안해주는거니?? 하는 마음이 들게됩니다 ㅠㅠ 자 오늘은 이 CORS 에러에 대해 간단하게 알아봅시다 CORS란? CORS는 Cross Origin Resource Sharing의 약자인데 직역하면 서로 다른 도메인간에 자원을 공유하는 것을 의미하며 기본적으로 브라우저에서 차단되어있습니다. 왜 차단시켜요..? 브라우저는 사실 공격에 굉장이 취약합니다. 누군가 의도적으로 악의적인 자바스크립트를 웹사이트에 심어놓는다면, Client의 ..