spring-data-relational
spring-data-relational copied to clipboard
Upgrade HSQL to 2.7.4
Simply upgrading the version property leads to
[ERROR] org.springframework.data.jdbc.repository.JdbcRepositoryEmbeddedWithReferenceIntegrationTests.deleteById -- Time elapsed: 0.001 s <<< ERROR!
org.springframework.data.relational.core.conversion.DbActionExecutionException: Failed to execute BatchWithValue{actions=[Insert{entity=org.springframework.data.jdbc.repository.JdbcRepositoryEmbeddedWithReferenceIntegrationTests$DummyEntity2@6cddb04c, propertyPath=embeddable.dummyEntity2, dependingOn=InsertRoot{entity=org.springframework.data.jdbc.repository.JdbcRepositoryEmbeddedWithReferenceIntegrationTests$DummyEntity@1c6d65f7, idValueSource=GENERATED}, idValueSource=GENERATED, qualifiers={}}], batchValue=GENERATED}
at org.springframework.data.jdbc.core.AggregateChangeExecutor.execute(AggregateChangeExecutor.java:118)
at org.springframework.data.jdbc.core.AggregateChangeExecutor.lambda$executeSave$0(AggregateChangeExecutor.java:61)
at org.springframework.data.relational.core.conversion.BatchedActions$InsertCombiner.lambda$forEach$2(BatchedActions.java:170)
at java.base/java.util.HashMap.forEach(HashMap.java:1429)
at org.springframework.data.relational.core.conversion.BatchedActions$InsertCombiner.lambda$forEach$3(BatchedActions.java:170)
at java.base/java.util.stream.ForEachOps$ForEachOp$OfRef.accept(ForEachOps.java:184)
at java.base/java.util.stream.SortedOps$SizedRefSortingSink.end(SortedOps.java:357)
at java.base/java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:510)
at java.base/java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:499)
at java.base/java.util.stream.ForEachOps$ForEachOp.evaluateSequential(ForEachOps.java:151)
at java.base/java.util.stream.ForEachOps$ForEachOp$OfRef.evaluateSequential(ForEachOps.java:174)
at java.base/java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234)
at java.base/java.util.stream.ReferencePipeline.forEach(ReferencePipeline.java:596)
at org.springframework.data.relational.core.conversion.BatchedActions$InsertCombiner.forEach(BatchedActions.java:169)
at org.springframework.data.relational.core.conversion.BatchedActions.forEach(BatchedActions.java:79)
at org.springframework.data.relational.core.conversion.SaveBatchingAggregateChange.forEachAction(SaveBatchingAggregateChange.java:71)
at org.springframework.data.jdbc.core.AggregateChangeExecutor.executeSave(AggregateChangeExecutor.java:61)
at org.springframework.data.jdbc.core.JdbcAggregateTemplate.performSave(JdbcAggregateTemplate.java:505)
at org.springframework.data.jdbc.core.JdbcAggregateTemplate.save(JdbcAggregateTemplate.java:171)
at org.springframework.data.jdbc.repository.support.SimpleJdbcRepository.save(SimpleJdbcRepository.java:69)
at java.base/jdk.internal.reflect.DirectMethodHandleAccessor.invoke(DirectMethodHandleAccessor.java:103)
at java.base/java.lang.reflect.Method.invoke(Method.java:580)
at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:359)
at org.springframework.data.repository.core.support.RepositoryMethodInvoker$RepositoryFragmentMethodInvoker.lambda$new$0(RepositoryMethodInvoker.java:277)
at org.springframework.data.repository.core.support.RepositoryMethodInvoker.doInvoke(RepositoryMethodInvoker.java:170)
at org.springframework.data.repository.core.support.RepositoryMethodInvoker.invoke(RepositoryMethodInvoker.java:158)
at org.springframework.data.repository.core.support.RepositoryComposition$RepositoryFragments.invoke(RepositoryComposition.java:515)
at org.springframework.data.repository.core.support.RepositoryComposition.invoke(RepositoryComposition.java:284)
at org.springframework.data.repository.core.support.RepositoryFactorySupport$ImplementationMethodExecutionInterceptor.invoke(RepositoryFactorySupport.java:752)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:184)
at org.springframework.data.repository.core.support.QueryExecutorMethodInterceptor.doInvoke(QueryExecutorMethodInterceptor.java:174)
at org.springframework.data.repository.core.support.QueryExecutorMethodInterceptor.invoke(QueryExecutorMethodInterceptor.java:149)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:184)
at org.springframework.data.repository.core.support.MethodInvocationValidator.invoke(MethodInvocationValidator.java:96)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:184)
at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:223)
at org.springframework.data.jdbc.repository.$Proxy162.save(Unknown Source)
at org.springframework.data.jdbc.repository.JdbcRepositoryEmbeddedWithReferenceIntegrationTests.deleteById(JdbcRepositoryEmbeddedWithReferenceIntegrationTests.java:165)
at java.base/java.lang.reflect.Method.invoke(Method.java:580)
at java.base/java.util.ArrayList.forEach(ArrayList.java:1596)
at java.base/java.util.ArrayList.forEach(ArrayList.java:1596)
Caused by: org.springframework.jdbc.UncategorizedSQLException: PreparedStatementCallback; uncategorized SQLException for SQL [INSERT INTO "DUMMY_ENTITY2" ("ID", "TEST") VALUES (?, ?)]; SQL state [24501]; error code [-3601]; invalid cursor state: identified cursor is not open
at org.springframework.jdbc.core.JdbcTemplate.translateException(JdbcTemplate.java:1557)
at org.springframework.jdbc.core.JdbcTemplate.execute(JdbcTemplate.java:677)
at org.springframework.jdbc.core.JdbcTemplate.execute(JdbcTemplate.java:695)
at org.springframework.jdbc.core.JdbcTemplate.batchUpdate(JdbcTemplate.java:1033)
at org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate.batchUpdate(NamedParameterJdbcTemplate.java:421)
at org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate.batchUpdate(NamedParameterJdbcTemplate.java:399)
at org.springframework.data.jdbc.core.convert.IdGeneratingBatchInsertStrategy.execute(IdGeneratingBatchInsertStrategy.java:77)
at org.springframework.data.jdbc.core.convert.DefaultDataAccessStrategy.insert(DefaultDataAccessStrategy.java:125)
at org.springframework.data.jdbc.core.JdbcAggregateChangeExecutionContext.executeBatchInsert(JdbcAggregateChangeExecutionContext.java:109)
at org.springframework.data.jdbc.core.AggregateChangeExecutor.execute(AggregateChangeExecutor.java:91)
... 40 more
Caused by: java.sql.SQLException: invalid cursor state: identified cursor is not open
at org.hsqldb.jdbc.JDBCUtil.sqlException(Unknown Source)
at org.hsqldb.jdbc.JDBCUtil.sqlException(Unknown Source)
at org.hsqldb.jdbc.JDBCUtil.sqlException(Unknown Source)
at org.hsqldb.jdbc.JDBCResultSet.checkClosed(Unknown Source)
at org.hsqldb.jdbc.JDBCResultSet.next(Unknown Source)
at org.springframework.jdbc.core.RowMapperResultSetExtractor.extractData(RowMapperResultSetExtractor.java:93)
at org.springframework.jdbc.core.JdbcTemplate.storeGeneratedKeys(JdbcTemplate.java:1591)
at org.springframework.jdbc.core.JdbcTemplate.lambda$getPreparedStatementCallback$7(JdbcTemplate.java:1619)
at org.springframework.jdbc.core.JdbcTemplate.execute(JdbcTemplate.java:658)
... 48 more
Caused by: org.hsqldb.HsqlException: invalid cursor state: identified cursor is not open
at org.hsqldb.error.Error.error(Unknown Source)
at org.hsqldb.error.Error.error(Unknown Source)
... 55 more
and similar
Since I was able to reproduce this directly with JDBC I opened an issue with HSQLDB: https://sourceforge.net/p/hsqldb/bugs/1725/
Somehow the ResultSet used for returning generated values is based on a closed cursor on the second attempt.
Code for reproduction:
@Test
@Order(1)
void dsOne() {
insertDataSource();
}
@Test
@Order(2)
void dsTwo() {
insertDataSource();
}
private void insertDataSource() {
try (Connection connection = dataSource.getConnection()) {
PreparedStatement preparedStatement = connection.prepareStatement(INSERT_MAIN + "(?, ?)", Statement.RETURN_GENERATED_KEYS);
preparedStatement.setInt(1, 4711);
preparedStatement.setString(2, "text1");
preparedStatement.executeUpdate();
try (ResultSet resultSet = preparedStatement.getGeneratedKeys()) {
while (resultSet.next()) {
System.out.println("rs element");
}
}
} catch (SQLException ex) {
throw new RuntimeException(ex);
}
}