Spring Data JPA를 사용해서 insert 시 아래와 같은 에러가 발생하지만 db table에는 데이터가 insert 현상이 발생했습니다.
13:54:04.844 [pool-2-thread-4] DEBUG o.h.r.j.i.ResourceRegistryStandardImpl 105 - HHH000387: ResultSet's statement was not registered
13:54:04.844 [pool-2-thread-4] ERROR jdbc.audit 128 - 1. PreparedStatement.getMaxRows()
java.sql.SQLSyntaxErrorException: (conn=2089043) Cannot do an operation on a closed statement
Service 클래스에서는 JpaRepository의 save함수를 통해서 insert를 하고 Entity 객체에는 PK 칼럼에 @GeneratedValue(strategy = GenerationType.IDENTITY) 설정이 되어 있습니다. @GeneratedValue(strategy = GenerationType.IDENTITY) 설정을 하면 기본 키 생성을 데이터베이스에 위임하게 됩니다.
Service 클래스
eventRepository.save(event);
Entity 클래스
@Id
@Column(name = "evt_no")
@GeneratedValue(strategy = GenerationType.IDENTITY)
private int evtNo;
저는 Spring boot 3.2.1을 사용하고 있는데 spring-boot-starter-data-jpa 3.2.1은 hibernate-core:6.4.1.Final 에 의존성을 가지고 있습니다.
+--- org.springframework.boot:spring-boot-starter-data-jpa -> 3.2.1
| +--- org.springframework.boot:spring-boot-starter-aop:3.2.1
| | +--- org.springframework.boot:spring-boot-starter:3.2.1 (*)
| | +--- org.springframework:spring-aop:6.1.2 (*)
| | \--- org.aspectj:aspectjweaver:1.9.21
| +--- org.springframework.boot:spring-boot-starter-jdbc:3.2.1
| | +--- org.springframework.boot:spring-boot-starter:3.2.1 (*)
| | +--- com.zaxxer:HikariCP:5.0.1
| | | \--- org.slf4j:slf4j-api:1.7.30 -> 2.0.9
| | \--- org.springframework:spring-jdbc:6.1.2
| | +--- org.springframework:spring-beans:6.1.2 (*)
| | +--- org.springframework:spring-core:6.1.2 (*)
| | \--- org.springframework:spring-tx:6.1.2
| | +--- org.springframework:spring-beans:6.1.2 (*)
| | \--- org.springframework:spring-core:6.1.2 (*)
| +--- org.hibernate.orm:hibernate-core:6.4.1.Final
제가 사용하고 있는 hibernate 버전에서는 Entity를 생성 후 id를 가져오면서 에러가 발생하는데 hibernate에서 catch하고 해당 에러를 전파하지 않기 때문에 쿼리를 실행하는데는 영향을 주지 않는다고 합니다.
삽입 후 생성된 값을 데이터베이스에서 검색하는 방법은 hibernate 6.5 버전에서 변경 된다고 합니다. 아직 해당 버전이 release 되지 않아 버전을 변경전에 에러 해결을 위해 아래와 같이 수정하였습니다.
Service 클래스
event.setEvtNo(eventRepository.findTopByOrderByEvtNoDesc().getEvtNo()+1)
eventRepository.save(event);
Repository 클래스
public interface EventRepository extends JpaRepository<Event, Integer> {
Event findTopByOrderByEvtNoDesc();
}
Entity 클래스
@Id
@Column(name = "evt_no")
private int evtNo;
기본키 생성을 데이터베이스에 위임하지 않고 Max값을 조회해서 만든 후 Entity 객체에 세팅한 후 insert를 하니 에러로그 없이 정상적으로 동작하는것을 확인하였습니다.
참고자료
https://www.javaguides.net/2023/08/spring-data-jpa-find-max-value.html
https://discourse.hibernate.org/t/duplicate-releases-of-statement-objects/8824
'개발 > spring, spring boot' 카테고리의 다른 글
[Spring Boot] [WebSocket] Protocol 설정 방법 (0) | 2024.02.20 |
---|---|
[Spring Data JPA] Entity가 복합키를 사용할때 JpaRepository 개발 방법 (0) | 2024.02.16 |
Spring Boot에서 JPA 사용하기 (0) | 2024.02.15 |
[Spring Boot] 서버 시작 시 WebSocket 연결 client java 로직 구현 (1) | 2024.02.08 |
[Spring Boot] mariadb-java-client vs mysql-connector-j (0) | 2024.02.07 |