6장. 값 타입 매핑

6.1.1 기본 프로퍼티 기본값 재정의 - @Transient, @Basic, @Column, @NotNull

6.1.2 프로퍼티 접근 방식 변경 - @Access(PROPERTY/FIELD)

6.1.3 파생 프로퍼티 활용 - @Formula

6.1.4 컬럼 값 변환 - @ColumnTransformer

6.1.5 생성되는 프로퍼티 값과 기본 프로퍼티 값 - @Generated

6.1.6 @Temporal 어노테이션

6.1.7 열거형 매핑 - @Enumerated(EnumType.String)

6.2 임베드 가능한 컴포넌트 매핑

6.2.2 클래스를 임베드 가능하게 만들기 - @Embeddable

@EmbeddabLe
public class Address { // equals, hashCode 재정의 필요
	@Notnull
	@Column(nullable = false, Length = 5)
	@Column(nullable = false)
	private String street;
	
	@NotNull
	private String zipcode;
	
	@NotNull
	@Column(nullable = false)
	private String city;

	public Address() {
	}

	public Address (String street, String zipcode, String city) {
		this.street = street;
		this.zipcode = zipcode;
		this.city = city;
	}

	// 게터
	
	// equals, hashCode 재정의
}
@Entity
@Table(name = "USERS")
public class User { 
	@Id
	@GeneratedValue(generator = Constants.ID_GENERATOR)
	private Long id;
	
	private Address homeAddress; // Address는 @Embeddable이므로, 애너테이션 지정 생략가능.
	
	//...
}

6.2.3 임베드된 속성 재정의 - @Embedded, @AttributeOverride

@Entity
@Table(name = "USERS")
public class User {
	//...
	
	@Embedded // 생략가능
	@AttributeOverride(name = "street", column = @column(name = "BILLING_STREET"))
	@AttributeOverride(name = "zipcode", column = @Column(name = "BILLING_2IPCODE", Length = 5))
	@AttributeOverride(name = "city", column = @Column(name = "BILLING_CITY"))
	private Address bilLingAddress;
	
	public Address getBillingAddress() {
		return billingAddress;
	}
	public void setBillingAddress(Address billingAddress) {
		this.billingAddress = bilLingAddress; 
	}
	
	//...	
}

6.2.4 중첩 임베드된 컴포넌트 매핑

@Embeddable
public class Address {
	@NotNull
	@Column(nullable = false)
	private String street;
	
	@NotNull
	@AttributeOverride(name = "name",	column = @Column(name = "CITY", nullable = false))
	private City city;
	
	// ....
}
@Embeddable
public class City {
	@NotNull
	@Column(nullable = false, length = 5)
	private String zipcode;
	
	@NotNull
	@Column(nullable = false)
	private String name;
	
	@NotNull
	@Column(nullable = false)
	private String country;

	// ...
}

6.3 변환기를 이용한 자바 타입과 SQL 타입의 매핑 - @Type, @Lob

6.3.1 내장 타입

Untitled

Untitled

Untitled

Untitled

Untitled

@Entity
public class Item {
	@Lob
	private byte[] image;

	@Lob
	private String description;
}
@Entity
public class Item {
	@Lob
	private Blob image;

	@Lob
	private Clob description;
}

타입 어댑터 선택하기 - @Type

QEntity
public class Item {
	@org.hibernate.anotations.Type(type = "yes_no")
	private boolean verified = false;
}

6.3.2 사용자 정의 JPA 변환기 생성 - @Convert


@NotNuLL
@Convert(converter = MonetaryAmountConverter.cLass)
@Column(name = "PRICE", Length = 63) 
private MonetaryAmount buyNowprice;
@Converter
public class MonetaryAmountConverter 
									implements AttributeConvertercMonetaryAmount, String> {
									
	@Override
	public String convertToDatabaseColumn(MonetaryAmount monetaryAmount) {
		return monetaryAmount.tostring();
	}
	
	@Override
	public MonetaryAmount convertToEntityAttribute(String s) {
		return MonetaryAmount.fromstring(s);
	}
									
}

컴포넌트의 프로퍼티 변환하기

public abstract class Zipcode {
	private string value;

	public zipcode(String value) {
		this.value = value; 
	}
		
	public string getValue() {
		return value;
	} 
	
	@Override
	public boolean equals(object o){
		if (this == o) return true;
		if (0 ==null il getclass() != 0.getclass()) return false;
		Zipcode zipcode = (Zipcode) 0;
		return objects.equals(value, zipcode.value);
	}
	
	@Override
	public int hashCode() {
		return Objects.hash(value);
	}
}
public class Germanzipcode extends Zipcode {
	public Germanzipcode(String value) {
		super(value);
	}
}
@Converter
public class Zipcodeconverter implements AttributeConverterczipcode, String> {

	@Override
	public string convertToDatabaseColumn(Zipcode attribute) {
		return attribute.getValue();
	}
	
	@Override
	public Zipcode convertToEntityAttribute(String s) {
		if (S.length() == 5) {
			return new GermanZipcode(s);	
		}
		if (S.length() == 4) {
			return new SwissZipcode(s);		
		}
		throw new IllegalArgumentException("Unsupported zipcode in database: " + s);
	}
	 
}
@Entity
@Table(name ="USERS")
public class user {
	// ...

	@Convert(converter = ZipcodeConverter.class, attributename = "city.zipcode")
	private Address homeAddress;
	
}

영속성 맵의 경우

JPA 변환기의 제약사항

6.3.3 UserType을 이용한 하이버네이트 확장

@org.hibernate.annotations.TypeDefs({ 
	@org.hibernate.annotations.TypeDef(
		name = "monetary_amount_usd",
		typeClass = MonetaryAmountuserType.class,
		parameters = {@parameter(name = "convertTo", value = "USD")}
	),
	@org.hibernate.annotations.TypeDef(
		name = "monetary_amount_eur",
		typeclass = MonetaryAmountuserType.class,
		parameters = {@parameter(name = "convertTo", value = "EUR")}
	)
})
package com.manning.javapersistence.ch06.converter;

import org.hibernate.annotations.Parameter;
@Entity
public class Item {
	@NotNull
	@org.hibernate.annotations.Type(
		type = "monetary_amount_usd"
	)
	@org.hibernate.annotations.Columns(columns ={
		@Column(name = "BUYNONPRICE_AMOUNT"),
		@Column(name = "BUYNOMPRICE_CURRENCY", Length = 3)
	})
	private MonetaryAmount buyNowprice;

	@NotNull
	@org.hibernate.annotations.Type(
		type = "monetary_amount_eur"
	)
	@org.hibernate.annotations.Columns(columns ={
		@Column(name = "INITIALPRICE_AMOUNT"),
		@Column(name = "INITIALPRICE_CURRENCY", Length = 3)
	})
	private MonetaryAmount initialprice;
	
	//...
}