jpa

    프로젝트 설계, 이체 시 동시성과 DB Isolation Level 고민 및 적용 - MiniPay(1)

    프로젝트 소개 최근 좋은 기회를 얻어서 작은 스터디를 시작하게 됐다. 스터디 운영하시는 분께서 너무 감사하게도 평소 프로젝트를 할 땐 신경 쓰지 않았던 부분들을 고민할 수 있는 주제로 프로젝트 아이디어를 제공해 주셨다.(동시성 문제, 성능 문제 등) 최근 CS의 중요성을 깨닫고 이걸 프로젝트에 어떻게 적용할지 고민이 많았는데 제공해준 프로젝트를 진행하면서 이런 고민을 해결할 수 있었다. 4개의 주제 중 페이 서비스를 만드는 것이 마음에 들었다. 평소 CRUD만 했던 DB를 Isolation Level과 락을 어떻게 걸지 고민하며 적용해 보는 것이 좋은 경험이 될 것이라고 생각했다. 또한 트랜잭션을 학습할 때 항상 이체를 예시로 들었는데 공부할 땐 예시만 보고 그렇구나~ 했던 것을 어떻게 해결할 것인지 고..

    [Querydsl] 순수 JPA Repository + Querydsl

    순수 JPA → Querydsl 변경 순수 JPA 사용 메소드 @Repository public class MemberJpaRepository { private final EntityManager em; private final JPAQueryFactory queryFactory; public MemberJpaRepository(EntityManager em){ this.em = em; this.queryFactory = new JPAQueryFactory(em); } public void save(Member member){ em.persist(member); } public Optional findById(Long id){ Member findMember = em.find(Member.class,id..

    @EntityListener로 생성일, 수정일 자동으로 넣기 + 프록시 활용(연관관계 Insert) - 게시판 만들기(13)

    이전에 회원가입, 로그인까지 만들었다. 나의 경우 간단하게 상세 정보도 만들어 1대 1 매핑을 했다. 이런 간단한 비즈니스들은 본인이 원하는 대로 만들면 될 것 같다. 게시글 Entity를 만들기 전에 게시글은 생성일, 수정일이 필요할 것 같아 해당 기능을 자동으로 하기 위해 JPA Auditing을 사용해보려고 한다. JPA Auditing JPA Auditing이란? JPA에서 시간 값을 자동으로 넣어주는 기능이다. Entity를 영속화 시키거나 조회를 수행한 후에 update를 하는 경우 매번 시간을 읽어와서 저장해 주는 번거로움이 있는데 JPA Auditing을 사용하면 자동으로 시간을 매핑하여 DB 테이블에 넣어준다. 사용하기 전에 이게 정말 좋을까?에 대한 생각이 들었다. 사실 자동으로 다 해..

    [JPA] 영속성 전이와 고아 객체

    영속성 전이 특정 Entity를 영속 상태로 만들 때 연관된 Entity도 함께 영속 상태로 만드는 것을 의미한다. 가령 부모 Entity를 저장할 때 자식 Entity도 함께 저장하는 것이다. 영속성 전이는 즉시 로딩, 지연 로딩, 연관 관계 설정과 관계없는 개념이다. @Entity public class Parent { @Id @GeneratedValue private Long id; @OneToMany(mappedBy = "parent") private List childList = new ArrayList(); public void addChild(Child child) { childList.add(child); child.setParent(this); } } @Entity public class..

    [JPA] 즉시 로딩과 지연 로딩

    만약 Member의 username만 사용하는 비즈니스라면 Team정보까지 불러오는 것은 추가적인 비용이 들어 손해이다. 이런 문제 때문에 JPA는 지연 로딩이라는 것을 지원한다. 지연 로딩 @Entity public class Member { @ManyToOne(fetch = FetchType.LAZY) @JoinColumn private Team team; } fetch = FetchType.LAZY 연관 관계 설정 어노테이션의 옵션으로 프록시 객체로 조회한다. 이전의 프록시는 해당 객체에 대해 직접적인 값을 사용할 때 DB에서 조회했다. 즉 프록시 객체로 조회하면 team을 출력하거나 응답하는등의 작업을 하지 않는다면 team은 조회되지 않는다. Team team = new Team(); team...

    [JPA] 프록시

    프록시 Member와 Team의 연관 관계에서 Member를 조회하면 항상 Team도 조회하는 것을 원하지 않을 수 있다. 지금 당장 나는 username만 필요하다면 굳이 Team을 조회할 필요가 없는 것이다. 만약 Team이 username을 조회할 때마다 조회된다면 추가적인 비용이 드는 것이니 손해이다. 이런 문제를 해결하기 위해선 먼저 프록시를 이해해야 한다. 프록시 기초 em.find() DB를 통해서 실제 Entity 객체를 조회하는 메소드 Member member = em.find(Member.class, memberId); member라는 객체 데이터를 사용하지 않고 find()만 해도 SELECT 쿼리를 실행한다. em.getReference() DB 조회를 미루는 프록시(가짜) Enti..

    [JPA] 다양한 연관 관계 매핑(다대일, 일대다, 일대일, 다대다)

    다대일(N:1) @ManyToOne 어노테이션으로 설정한다. 다대일(N:1)은 N이 연관 관계의 주인이다. 다대일 관계는 가장 많이 사용하는 연관 관계이다. 단방향 Member가 N, Team이 1이다. 이때 N이 외래키를 가지며 관계의 주인이 된다. 외래키가 있는 곳에 참조를 걸고 연관 관계 매핑을 하면 된다. 양방향 양방향이 테이블에 영향을 주지는 않는다. 테이블은 FK로 관계를 풀기 쉽지만 객체의 경우는 같은 방법으로는 불가능하기 때문에 단방향 관계를 양쪽에서 설정하여 해결한다. 어차피 연관 관계의 주인이 외래 키를 관리하기 때문에 객체에서 양방향 관계를 추가하면 된다. 일대다(1:N) @OneToMany 어노테이션으로 설정한다. 일대다(1:N)는 1이 연관 관계의 주인인 방법이다. 추천하지 않는 ..

    [JPA] 연관 관계

    단방향 연관 관계 @Entity public class Member { private Long id; @Column(name = "USERNAME") private String name; @ManyToOne @JoinColumn(name = "TEAM_ID") private Team team; } @Entity public class Team { @Id @GeneratedValue private Long id; private String name; } 객체 지향적으로 모델링을 하면 Member에는 TEAM_ID가 아니라 TEAM 참조값을 그대로 가지게 된다. 내가 속하는 팀 그 자체를 가지는 것이다. Team team = new Team(); team.setName("TeamA"); em.persist(..