DevBoi

[JPA] 값 타입 본문

Develop/[JPA]

[JPA] 값 타입

HiSmith 2022. 3. 10. 16:02
반응형

엔티티 타입

@Entity로 정의하는 객체

데이터가 변해도 식별자로 지속해서 추적가능

예_ 회원 엔티티의 키나 나이값을 변경해도 식별자로 인식가능

 

값 타입

int,Integer,문자열 처럼 단순히 값으로 사용하는 자바 기본타입이나 객체

식별자가 없고, 값만 있으므로 변경시 추적불가

예_숫자 100을 200으로 변경하면 완전히 다른 값으로 대체 된다.

 

-값타입_ 기본값 타입

-자바 기본타입 -int,long -> 공유가 되지 않는 객체

-래퍼 클래스 -Integer,Long -> 공유가 가능하지만, 변경되면 안된다.

-String

 

-값타입_임베디드 타입

 

 

JPA에서 임베디드한, 데이터 값을 이런식으로 컬럼으로 가질수있다.

이렇게하면, 하위 속성들이 별도 컬럼으로 생성이된다.

이렇게 사용하면 재사용 성이 높고, 응집도가 높아지며, 내부에서 유의미한 메소드를 사용할수도, 생성할수도있다.

 

만약에 한 객체에서, Company에 대한 임베디드 한 객체 2개를 사용하는경우에는 해당과 같이 attributeoverride를 해주면된다.

 

값타입에서는, 이런경우, t2는 t1의 값이 복사되는 것이 아닌 같은 인스턴스의 주소를 가르키게 되기때문에

해당 값이 T2가 생성된 이후에 바뀌어도 T2는 다시 바뀌게 된다.

 

 

해당 부분은 프리미티브 타입이랑 다른 점이다.

하여 해당 부분 객체의 값이 변경되지 않게 불변 객체를 사용한다.

엔티티 관련되서의 값이 이렇게 참조 문제로 변경되면 안되기 때문에 생성자로만 값을 컨트롤한다

 

 

 

만약에 바꾸고 싶다면, 새롭게 생성자를 통해서 넣으면 된다.

 

Collection 타입에 대한 컬럼을 사용한다고하면,

별도 테이블을 생성해야한다.

해당 별도로 생성이 되기 때문에 조인이 되는 컬럼을 지정해줘야 한다는 것이 중요하다.

해당 조인컬럼을 지정 해주면 해당 컬럼을 바탕으로 테이블이 생성된다.

 

또한 해당 , member 하위에, 값타입을 사용해서 컬렉션을 사용한다고 가정해보자, 이런 경우에도

값타입 컬렉션은 Member하위에 있기 때문에, 별도 라이프사이클을 가지지 않고, 멤버의 라이프사이클을 따라서 종속 된다.

 

이는 Casecade를 사용해서, 해당 영속성 전이 시키는 성질 과 비슷하다

 

만약에 이런 소스가 있다고 가정해보자,

이렇게 되어있다면, 별도 지연 로딩 설정을 하지 않았기 때문에, em.find로 조회를 했을떄 해당 값을 바로 가져올수있어야 한다.

하지만, 결과는

 

 

이렇게 되어있다, 로그가 좀 지저분 하지만 결론은 한 엔티티 하위에 있는 값타입 다른 엔티티, 컬렉션 타입 이던 뭐던

해당 컬렉션 값타입으로 선언된 것은 자동으로 지연 로딩의 대상이 되는 것이다.

컬렉션 값타입으로 설정하면, 별도 테이블이 생성되긴 하지만, 자동 지연로딩이 된다는 점을 알아두면 될 것같다.

 

그러면 한번 빼볼까?

빼도, 사실 완전로딩은 아니다. 왜냐면, oneToMany는 디폴트가 지연로딩 이기때문이다.

ManyToOne이나 oneToone같이 디폴트 검색이 완전 로딩인 경우에는 해당 문제가 발생할수있다.

무튼, 디폴트로 지연 로딩이 되어있는 방법에 대해서 값타입을 사용하면, 지연로딩으로 변경된다는 점을 참고하자

 

추가로, 값타입은 immutable해야하기때문에 수정하기 위해서는, 새로운 생성자로 add하거나 set을 해줘야한다.

 

값타입은 엔티티와 다르게 식별자의 개념이 없다.

따라서, 값 타입의 값이 변경되면, 해당 주인 엔티티의 값이 모두 제거되고, 나머지 남은값들을 다시 insert한다.

즉 값을 변경하면 해당 값에 대한 추적이 어렵다.

 

-> 따라서 쓰면 안된다.실무에서는 일대다로 하는것을 추천한다.

완전 간단한 정도의 값인 경우에만, 해당 값타입을 쓰고, 아닌 경우에는 일대다 관계를 하는것이 좋다

 

 

 

해당 값타입 보다 엔티티를 지향하는 이유는

그냥 단순히, 값타입에 대한 수정을 하려고할때, 바로 느껴진다.

우선 식별자가 없기때문에 수정을 할때 해당 값만 수정을 하려면 OrderColumn을 사용하여 복잡하게 관리를 해야한다.

그래서, 그냥 수정할 일이 있거나, 해당 테이블 타겟으로 데이터를 조회하는 경우에는 엔티티를 쓰는것이 좋다 

반응형

'Develop > [JPA]' 카테고리의 다른 글

[JPQL] JPQL 시작하기  (0) 2022.03.10
[JPA] JPQL 공부 시작하기전에...  (0) 2022.03.10
[JPA] 영속성 전이  (0) 2022.03.07
[JPA] 지연로딩과 즉시로딩  (0) 2022.03.07
[JPA] 프록시객체에 대한 이해  (0) 2022.02.17