티스토리 뷰
* 개요
Hibernate 에서 composite key (복합키) 로 선언했을 때 하나의 컬럼은 자동 생성이 가능한가?
ex : INSERT 그룹명은 지정해주고, 그룹내 번호는 DBMS 에 의해 자동 생성되는 경우
* 일반적인 composite id 선언 - 어노테이션 이용
- composite id 선언시는 그냥 @Id 두개 붙이면 됨.
- 하나의 컬럼을 자동생성하려면 해당 컬럼에 @GeneratedValue 선언으로 사용 가능
MySQL 의 경우
1. numInGroup 컬럼에 Auto Increment 선언,
2. 매핑되는 필드에 @GeneratedValue (strategy=GenerationType.IDENTITY)
* 일반적인 composite id 선언 - XML
hbm.xml 에 다음과 같이 선언
<composite-id>
<key-property name="groupName" column="groupName"/>
<key-property name="numInGroup" column="numInGroup" />
</composite-id>
- numInGroup 이 자동생성 되게 하려면?
MySQL 의 경우 numInGroup 에 Auto Increment 선언해주면 됨.
하이버네이트 설정해서는 해줄게 없음.
* save 후에 자동생성된 key 받아오는 방법 (XML 선언의 경우)
- 위의 예시에서 '그룹명'만 지정해서 INSERT 했을때, 자동 생성된 '그룹내 번호' 를 받아오는 방법
=> 불가능
composite id 는 generation 이 아니라 assignment 라 안된다?
- 다음과 같이 Generator 설정해주면 되지 않을까?
<composite-id>
<key-property name="groupName" column="groupName"/>
<key-property name="numInGroup" column="numInGroup" />
<generator class="identity" />
</composite-id>
=> 불가.
위와 같이 선언하고,
groupName = "A"
numInGroup = null 로 save() 해도
하이버네이트가 두개 컬럼 모두 INSERT SQL 에서 제외시킴.
(두 컬럼 모두 값의 생성을 DB에 위임한다고 판단)
따라서 다음 오류 발생함
SQL state [HY000];
error code [1364]; Field 'groupName ' doesn't have a default value;
nested exception is java.sql.SQLException: Field 'groupName' doesn't have a default value
generator class 를 하나의 컬럼에 적용해야 하는데 그런 방법이 없음.
- 결론 : 불가능.
우회하는 방법으로 마지막 row 를 가져와서 직접 numInGroup 을 지정해주는 코드를 작성해야 함
You cannot use an IdentifierGenerator to generate composite keys. Instead the application must assign its own identifiers.
https://docs.jboss.org/hibernate/orm/3.3/reference/ko-KR/html/components.html#components-compositeid
* 참고 : Hibernate Auto increment 적용 방법
https://jojoldu.tistory.com/295
https://thoughts-on-java.org/jpa-generate-primary-keys/
@GeneratedValue 선언으로 사용 가능
기본값은 (strategy=GenerationType.AUTO)
AUTO | 하이버네이트가 알아서 선택함 |
IDENTITY | DB 에 위임. ex : MySQL 컬럼이 AUTO-INCREMENT 로 선언된 경우 사용 가능 |
SEQUENCE | DB에서 마지막 키값을 조회 후 다음 값으로 결정함. (추가 SELECT 가 필요) |
TABLE | DB 에 키 생성 전용 테이블을 별도로 생성(하이버네이트가 관리해줌) |
* 기타 : EmbeddedId 사용
https://vladmihalcea.com/the-best-way-to-map-a-composite-primary-key-with-jpa-and-hibernate/
- get 할때
https://stackoverflow.com/questions/1886648/hibernatetemplate-composite-key-fetching-value-null
'SW개발 > Hibernate' 카테고리의 다른 글
javax.persistence.TransactionRequiredException: Executing an update/delete query (0) | 2018.05.21 |
---|---|
tx:annotation-driven" 요소에 대한 "tx" 접두어가 바인드되지 않았습니다. (0) | 2018.05.21 |
hibernate / SQL Error: 0, SQLState: 08001 등 (0) | 2018.05.10 |
hibernate / java.net.NoRouteToHostException: 호스트로 갈 루트가 없음 (Host unreachable) (0) | 2018.05.10 |
Hibernate 2개 이상의 DB 연결 (0) | 2018.05.10 |