Java/JPA

    [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(..

    [JPA] Entity 매핑

    객체와 테이블 매핑 @Entity JPA가 관리하는 객체를 Entity라고 한다. JPA를 사용해서 테이블과 매핑할 클래스는 @Entity 어노테이션을 필수로 달아줘야 한다. 파라미터가 없는 public 또는 protected생성자를 필수로 구현해야 하며 final 클래스, enum, interface, inner클래스에 사용할 수 없다. 그리고 DB에 저장할 필드에도 final을 사용할 수 없다. name 속성 JPA에서 사용할 Entity의 이름을 지정한다. 기본값으로 클래스 이름을 그대로 사용한다. 같은 이름이 있는게 아니라면 가급적 기본값을 사용하도록 한다. @Table Entity와 매핑할 테이블을 지정한다. name 속성 매핑할 테이블 이름을 지정한다. 실제 쿼리도 name에 지정된 테이블로 ..

    [JPA] 개념 정리(영속화, 영속성 컨텍스트)

    여태 spring-boot-starter-data-jpa 가 JPA의 전부인 줄 알았지만 아니었다. Java에서 대표적인 ORM이 JPA이고(표준이 되었음) 그 구현체 Hibernate가 있는 것과 객체는 객체답게, RDB는 RDB답게 설계하면 ORM 프레임워크가 자동으로 매핑해주는 것, DB에 종속적이지 않은 것 등은 알고 있었다. 그래서 JPA가 뭔지 더 찾아보니 기존에 내가 사용하던 것들의 원리를 알 수 있었다. JPA의 원리 JPA 동작 JPA는 어플리케이션과 JDBC 사이에서 동작한다. 어플리케이션에서 JPA로 명령을 하면 JPA가 해석해서 JDBC API를 사용하여 SQL을 실행하고 그 결과를 반환받는다. 그래서 findAll()과 같은 자바스러운 메소드를 사용해도 변환해서 SELECT * ~..