본문 바로가기
  • 개발공부 및 일상적인 내용을 작성하는 블로그 입니다.
JPA

실전 예제 6 - 값 타입

by 방구석 대학생 2020. 10. 22.

"인프런 - 자바 ORM 표준 JPA 프로그래밍 강의를 듣고 작성한 글 입니다."

www.inflearn.com/course/ORM-JPA-Basic#

 

자바 ORM 표준 JPA 프로그래밍 - 기본편 - 인프런

JPA를 처음 접하거나, 실무에서 JPA를 사용하지만 기본 이론이 부족하신 분들이 JPA의 기본 이론을 탄탄하게 학습해서 초보자도 실무에서 자신있게 JPA를 사용할 수 있습니다. 초급 웹 개발 프로그

www.inflearn.com

 

 

1.실전 예제 프로젝트에서 값 타입(임베디드 타입) 으로 사용할 수 있는 주소와 같은 속성들을 묶어서 Address 로 만든다.

 

2.이후 Member, Delivery 클래스에서 임베디드 타입으로 사용할 Address 에 소속될 필드들을 지워준 후 Address 클래스를 만들어준다.

 

3. Address 클래스에 @Embeddable 어노테이션을 선언해 줌으로서 임베디드 타입으로 지정해 준 후 Member, Delivery 클래스에서 지운 필드들과 Getter, Setter 코드를 작성해준다.

(Setter 의 경우 불변 객체로 만들어야 하기 때문에, 클래스 내부에서만 해당 메소드를 사용할 수 있게끔 private 으로 메소드를 선언해준다.)

 

 

4. 이후 equals, hashCode 메소드를 오버라이드 하여 가져와준다.

참고 - equals, hashCode 메소드를 오버라이드 할 때 Use getters during code generation 옵션을 사용해 주는 것이 좋다.

왜냐하면 해당 옵션을 선택하면 Getter 를 호출하게 되는데, 옵션을 선택하지 않을 경우 메소드를 호출 할 때 Getter 를 사용하는 것이 아니라 필드에 직접 접근을 하게 된다.

그럴 경우 프록시 객체의 경우엔 계산을 하지 못하게 되는 것이다.

- Getter 메소드를 사용해야 프록시 객체가 가리키고 있는 실제 Entity 값을 가져올 수 있다.

- JPA 에서는 프록시를 고려하여 항상 메소드를 통해 값을 호출하도록 equals, hashCode 메소드를 구성하는 것이 좋다.

 

5. 그렇게 Address 구성이 끝나면 원래 Address 클래스의 필드를 가지고 있던 Member, Delivery 클래스에 @Embedded 어노테이션(생략해도 무방하다) 을 이용하여 Address 클래스의 객체를 선언해준 후 Getter, Setter 코드 까지 작성을 해준 다음 애플리케이션을 실행해보자.

 

- Address.java

@Embeddable
public class Address {

	private String city;
	private String street;
	private String zipcode;

	public String getCity() {
		return city;
	}

	public String getStreet() {
		return street;
	}

	public String getZipcode() {
		return zipcode;
	}

	private void setCity(String city) {
		this.city = city;
	}

	private void setStreet(String street) {
		this.street = street;
	}

	private void setZipcode(String zipcode) {
		this.zipcode = zipcode;
	}

	@Override
	public boolean equals(Object o) {
		if (this == o) return true;
		if (o == null || getClass() != o.getClass()) return false;
		Address address = (Address) o;
		return Objects.equals(getCity(), address.getCity()) &&
				Objects.equals(getStreet(), address.getStreet()) &&
				Objects.equals(getZipcode(), address.getZipcode());
	}

	@Override
	public int hashCode() {
		return Objects.hash(getCity(), getStreet(), getZipcode());
	}
}

 

- Member.java, Delivery.java

@Embedded
private Address address;

// Getter, Setter

 

- hibernate SQL

Hibernate: 
    
    create table Member (
       MEMBER_ID bigint not null,
        createdBy varchar(255),
        createdDate timestamp,
        lastModifiedBy varchar(255),
        lastModifiedDate timestamp,
        city varchar(255), // 임베디드 타입 Address 의 필드 들이 잘 생성 되어 있는 것을 확인 할 수 있다. 
        street varchar(255),
        zipcode varchar(255),
        name varchar(255),
        primary key (MEMBER_ID)
    )
Hibernate: 
    
    create table Delivery (
       id bigint not null,
        createdBy varchar(255),
        createdDate timestamp,
        lastModifiedBy varchar(255),
        lastModifiedDate timestamp,
        city varchar(255), // 임베디드 타입 Address 의 필드 들이 잘 생성 되어 있는 것을 확인 할 수 있다. 
        street varchar(255),
        zipcode varchar(255),
        status integer,
        primary key (id)
    )

 

 

* 값 타입을 사용할 때 어떤 장점이 있을까?

- 임베디드 타입 클래스 안에서 의미 있는 메소드들을 만들어 줄 수 있다.

- 각 필드들에 @Column 어노테이션 들을 사용해 줄 수 있다.

'JPA' 카테고리의 다른 글

JPQL - JPQL 소개(2)  (0) 2020.11.13
JPQL - JPQL 소개(1)  (0) 2020.11.13
값 타입 - 값 타입 컬렉션(2)  (0) 2020.10.22
값 타입 - 값 타입 컬렉션(1)  (0) 2020.10.22
값 타입 - 불변 객체와 값 타입 비교(2)  (0) 2020.10.22