Sunday Study

Hibernate Jpa 1

0. 사전 지식

image

참고) 데이터베이스 접근 기술 분류

JPA

JPA 구성 요소

  1. javax.persistance 패키지로 정의된 API 그 자체
  2. JPQL(Java Persistence Query Language)
  3. 객체/관계 메타데이터

Hibernate

1. Hibernate 아키텍처

전체 아키텍처 관점

image

Hibernate API 관점

image

Configuration(설정)

Session Factory

image

Most applications create a Hibernate SessionFactory singleton that’s cached for the lifecycle of the app because the object is resource-intensive to create.

Session

image

Query

Transaction

image

Persistent objects

First-level cache

Second-level-cache

1차, 2차 캐시 및 Hibernate & EhCache 관련 내용

[JPA & Hibernate] First Level Cache & Second Level Cache

2. 도메인 모델

매핑 유형

기본 값

기본 값 타입은 흔히 말하는 primitive type 과 Wrapper Class와

더불어 몇가지 클래스들을 포함

image

@Basic

@Entity(name = "Product")
public class Product {

	@Id
	@Basic
	private Long id;

	@Basic
	private String name;
}

Hibernate ORM 6.2.3.Final User Guide

image

@Column

@Entity
public class User {
    @Id
    Long id;

    @Column(columnDefinition = "varchar(255) default 'John Snow'")
    private String name;

    @Column(columnDefinition = "integer default 25")
    private Integer age;

    @Column(columnDefinition = "boolean default false")
    private Boolean locked;
}

@Formula

image

Hibernate는 기본 값을 어떻게 SQL에 매핑할까?

해당 내용은 Hibernate 6.0 버전에서 수정되었다…

@Enumerated

public enum PhoneType {
		LAND_LINE, MOBILE;
}

Boolean

Byte, Short, Integer, Long, BigInteger

Double, Float, BigDemical

Character

String

@Lob → String에 사용

@Nationalized → String에 사용

[SQL Server 에게 String 이란? (NVARCHAR 인가 VARCHAR 인가) 우아한형제들 기술블로그](https://techblog.woowahan.com/2605/)

LocalDate, LocalDateTime, LocalTime

UUID

Embeddable & Embedded

Embedded 타입 재정의

@Entity
public class Member {
  
  @Id @GeneratedValue
  private Long id;
  private String name;
  
  @Embedded
  Address homeAddress;
  
  @Embedded
  @AttributeOverrides({
    @AttributeOverride(name="city", column=@Column(name="COMPANY_CITY")),
    @AttributeOverride(name="street", column=@Column(name="COMPANY_STREET")),
    @AttributeOverride(name="zipcode", column=@Column(name="COMPANY_ZIPCODE"))
  })
  Address companyAddress;
}

@EmbeddedId

엔티티 타입

@Id

@Entity

@Table

엔티티에서의 Equals와 HashCode 재정의

네이밍 전략

image

접근 전략

필드 접근 방식

속성 기반 접근 방식

@Id
public Long getId() {
		return this.id;
}

필드 접근 방식의 장점

  1. 불필요한 getter, setter 구현 불필요
  2. 프록시 작업시 버그 방지
    1. Hibernate는 getter 메소드를 호출하는 시점에 값을 초기화 한다.
    2. equals를 프록시 객체로 사용하는 코드가 실행되면, equals는 필드를 직접 접근하기 때문에 npe와 같은 오류가 발생한다.

식별자

@Id

@GeneratedValue

Optimizer

@EmbeddedId

@IdClass

@IdClass(UserId.class)
@Entity
public class User {

    @Id
    @Column(name = "USER_ID")
    private String id;

    @Id
    @Column(name = "REG_DATE")
    private LocalDateTime regDate;

    // 생략

}
@AllArgsConstructor
@NoArgsConstructor
public class UserId implements Serializable {

    private String id;
    private LocalDateTime regDate;

    // equals & hashCode 부분 생략
}

Associations (관계 설정)

ManyToOne

OneToMany

OneToOne

Any

@Entity
@Table(name = "property_holder")
public class PropertyHolder {

    @Id
    private Long id;

    @Any
    @AnyDiscriminator(DiscriminatorType.STRING)
    @AnyDiscriminatorValue(discriminator = "S", entity = StringProperty.class)
    @AnyDiscriminatorValue(discriminator = "I", entity = IntegerProperty.class)
    @AnyKeyJavaClass(Long.class)
    @Column(name = "property_type")
    @JoinColumn(name = "property_id")
    private Property property;

    //Getters and setters are omitted for brevity

}

ManyToAny

@Entity
@Table(name = "property_repository")
public class PropertyRepository {

    @Id
    private Long id;

    @ManyToAny
    @AnyDiscriminator(DiscriminatorType.STRING)
    @Column(name = "property_type")
    @AnyKeyJavaClass(Long.class)
    @AnyDiscriminatorValue(discriminator = "S", entity = StringProperty.class)
    @AnyDiscriminatorValue(discriminator = "I", entity = IntegerProperty.class)
    @Cascade(ALL)
    @JoinTable(name = "repository_properties",
            joinColumns = @JoinColumn(name = "repository_id"),
            inverseJoinColumns = @JoinColumn(name = "property_id")
   )
    private List<Property<?>> properties = new ArrayList<>();

    //Getters and setters are omitted for brevity

}

ManyToMany

컬렉션

@ElementCollection

Natural Id

@NaturalId

Partitioning

@PartitionKey

파티셔닝을 위한 파티셔닝 키를 지정한다. 필드위에 붙인다.

Dynamic Model

→ XML 파일 사용하는 내용이므로 PASS

상속

@MappedSuperclass

단일 테이블 전략

@Inheritance(strategy = InheritanceType.SINGLE_TABLE)

image

@DiscriminatorFormula(
	"case when debitKey is not null " +
	"then 'Debit' " +
	"else (" +
	"   case when creditKey is not null " +
	"   then 'Credit' " +
	"   else 'Unknown' " +
	"   end) " +
	"end "
)

조인 테이블 전략

@Inheritance(strategy = InheritanceType.JOINED)

image

구현 클래스별 테이블 전략

@Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)

image

Mutability

불변 엔티티 → @Immutable 을 클래스 레벨에 붙인다.

불변 속성 → @Immutable 을 필드 레벨에 붙인다.

불변 컬렉션 → @Immutable 을 컬렉션 필드에 붙인다.

도메인 모델 Customizing

→ 지엽적인 내용이므로 PASS