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()

- 현재 엔티티(애노테이션이 적용된 클래스)가 매핑할 테이블의 컬럼