Java/JPA with Error
[해결 방법] org.hibernate.exception.ConstraintViolationException
HJ0216
2023. 9. 19. 21:42
👉 기본 환경
- Language: Java
- DB: H2 Database
- IDE: IntelliJ
⌨️ 코드
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
|
@Entity
public class MemberClctn {
@Id
@GeneratedValue
private long id;
private String username;
// Address
@Embedded
private Address homeAddress;
@ElementCollection
@CollectionTable(name = "FAVORITE_FOOD",
joinColumns = @JoinColumn(name = "id"))
private Set<String> favoriteFoods = new HashSet<>();
@OneToMany(cascade = CascadeType.ALL, orphanRemoval = true)
@JoinColumn(name = "id")
private List<AddressEntity> addressesHist = new ArrayList<>();
}
|
🖨️오류
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
|
ERROR: Referential integrity constraint violation: "FKAXD8WBKC203QQ3EKY4KJIV7MO: PUBLIC.ADDRESS FOREIGN KEY(ID) REFERENCES PUBLIC.MEMBERCLCTN(ID) (3)"; SQL statement:
/* insert jpa_basic.AddressEntity */ insert into ADDRESS (city, street, zipcode, id) values (?, ?, ?, ?) [23506-200]
javax.persistence.PersistenceException: org.hibernate.exception.ConstraintViolationException: could not execute batch
at org.hibernate.internal.ExceptionConverterImpl.convert(ExceptionConverterImpl.java:154)
at org.hibernate.internal.ExceptionConverterImpl.convert(ExceptionConverterImpl.java:181)
at org.hibernate.internal.ExceptionConverterImpl.convert(ExceptionConverterImpl.java:188)
at org.hibernate.internal.SessionImpl.doFlush(SessionImpl.java:1356)
at org.hibernate.internal.SessionImpl.flush(SessionImpl.java:1339)
at jpa_basic.Main.main(Main.java:526)
Caused by: org.hibernate.exception.ConstraintViolationException: could not execute batch
at org.hibernate.exception.internal.SQLStateConversionDelegate.convert(SQLStateConversionDelegate.java:109)
at org.hibernate.exception.internal.StandardSQLExceptionConverter.convert(StandardSQLExceptionConverter.java:42)
at org.hibernate.engine.jdbc.spi.SqlExceptionHelper.convert(SqlExceptionHelper.java:113)
at org.hibernate.engine.jdbc.batch.internal.BatchingBatch.performExecution(BatchingBatch.java:129)
at org.hibernate.engine.jdbc.batch.internal.BatchingBatch.doExecuteBatch(BatchingBatch.java:105)
at org.hibernate.engine.jdbc.batch.internal.AbstractBatchImpl.execute(AbstractBatchImpl.java:148)
at org.hibernate.engine.jdbc.internal.JdbcCoordinatorImpl.executeBatch(JdbcCoordinatorImpl.java:198)
at org.hibernate.engine.spi.ActionQueue.executeActions(ActionQueue.java:633)
at org.hibernate.engine.spi.ActionQueue.lambda$executeActions$1(ActionQueue.java:478)
at java.base/java.util.LinkedHashMap.forEach(LinkedHashMap.java:684)
at org.hibernate.engine.spi.ActionQueue.executeActions(ActionQueue.java:475)
at org.hibernate.event.internal.AbstractFlushingEventListener.performExecutions(AbstractFlushingEventListener.java:348)
at org.hibernate.event.internal.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:40)
at org.hibernate.event.service.internal.EventListenerGroupImpl.fireEventOnEachListener(EventListenerGroupImpl.java:102)
at org.hibernate.internal.SessionImpl.doFlush(SessionImpl.java:1352)
... 2 more
Caused by: org.h2.jdbc.JdbcBatchUpdateException: Referential integrity constraint violation: "FKAXD8WBKC203QQ3EKY4KJIV7MO: PUBLIC.ADDRESS FOREIGN KEY(ID) REFERENCES PUBLIC.MEMBERCLCTN(ID) (2)"; SQL statement:
/* insert jpa_basic.AddressEntity */ insert into ADDRESS (city, street, zipcode, id) values (?, ?, ?, ?) [23506-200]
at org.h2.jdbc.JdbcPreparedStatement.executeBatch(JdbcPreparedStatement.java:1235)
at org.hibernate.engine.jdbc.batch.internal.BatchingBatch.performExecution(BatchingBatch.java:119)
... 13 more
|
📡 원인
AddressEntity와 일대다 매핑키 키 이름을 id로 부여하고자 함
= MemberClctn의 PK값을 AddressEntity의 FK로 사용
이 때, FK로 사용하고자 하는 컬럼을 AddressEntity의 id 필드로 지정하여 MemberClctn의 기본 키를 참조하는 외래 키로 간주
PK값이 중복된 값을 갖을 수 없으므로 무결성 제약 조건 위반 오류 발생
📰 해결 방법
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
|
@Entity
public class MemberClctn {
@Id
@GeneratedValue
private long id;
private String username;
// Address
@Embedded
private Address homeAddress;
@ElementCollection
@CollectionTable(name = "FAVORITE_FOOD",
joinColumns = @JoinColumn(name = "id"))
private Set<String> favoriteFoods = new HashSet<>();
@OneToMany(cascade = CascadeType.ALL, orphanRemoval = true)
@JoinColumn(name = "MCLCTN_NAME")
private List<AddressEntity> addressesHist = new ArrayList<>();
}
|
FK값을 갖는 새로운 Col 생성
⭐ @JoinColumn()
- 현재 엔티티(애노테이션이 적용된 클래스)가 매핑할 테이블의 컬럼