Add Hibernate 7 batches 2-6, batch 7, and batch 8: mapping styles, JPA annotations, natural IDs, @Immutable, stored procedures, in-memory test databases, JNDI mocking, proxies, associations, temporal mapping, named queries, HQL, Criteria API, EntityManager bootstrapping, Ehcache 3 L2 cache configuration, HikariCP connection pooling, Hibernate Validator CDI integration, aggregate functions, sorting, pagination, interceptors, and Hibernate Search 8 (Hibernate 7.4.5.Final + Spring Boot 4.1.1 + JDK 25)
This commit is contained in:
+56
@@ -0,0 +1,56 @@
|
||||
=== Raw JDBC probe (no Hibernate), HSQLDB 2.7.3, DYNAMIC RESULT SETS procedure ===
|
||||
--- CallableStatement.execute() then getUpdateCount()/getResultSet() ---
|
||||
execute() returned=false
|
||||
getUpdateCount=0
|
||||
getResultSet() = org.hsqldb.jdbc.JDBCResultSet@5649fd9b
|
||||
row: 1 Alice 50000.00
|
||||
row: 2 Bob 60000.00
|
||||
getMoreResults=false
|
||||
|
||||
--- Statement.execute("CALL ...") vs CallableStatement.executeQuery() ---
|
||||
--- via plain Statement.execute(CALL ...) ---
|
||||
Statement.execute returned=false
|
||||
getResultSet=null
|
||||
--- via CallableStatement.executeQuery() ---
|
||||
executeQuery ok, rs=org.hsqldb.jdbc.JDBCResultSet@5649fd9b
|
||||
row via executeQuery: 1
|
||||
row via executeQuery: 2
|
||||
--- metadata: getMetaData() on CallableStatement before execute ---
|
||||
getMetaData()=null
|
||||
|
||||
CONCLUSION: CallableStatement.execute() returns false (per JDBC spec this should mean
|
||||
'no ResultSet, check update count'), and getUpdateCount() also returns 0 (not -1).
|
||||
Yet CallableStatement.getResultSet() DOES return a live, iterable ResultSet with the
|
||||
cursor's rows, and CallableStatement.executeQuery() works correctly end-to-end.
|
||||
Statement.execute("CALL ...") is worse: execute()=false AND getResultSet()=null (the
|
||||
result set is only reachable through the CallableStatement form).
|
||||
Hibernate 7.4.5's ProcedureCallImpl (org.hibernate.procedure.internal.ProcedureCallImpl
|
||||
/ StandardCallableStatementSupport) drives the call via execute() and trusts its boolean
|
||||
to decide whether to attach a ResultSetOutput. Since HSQLDB's driver misreports that
|
||||
boolean, getResultList() on a DYNAMIC RESULT SETS procedure fails with:
|
||||
java.lang.IllegalStateException: Current CallableStatement was not a ResultSet, but getResultList was called
|
||||
This reproduces identically through @NamedStoredProcedureQuery(resultClasses=...) and
|
||||
through createStoredProcedureQuery(name, sqlResultSetMappingName) -- see
|
||||
StoredProcedureHappyPathTest#resultSetProcedure_mappedToEntity_hitsHsqldbDriverIncompatibility
|
||||
and #resultSetProcedure_mappedToDto_alsoHitsHsqldbDriverIncompatibility.
|
||||
|
||||
=== OUT parameter vs result-set consumption ORDER (raw JDBC, procedure with BOTH) ===
|
||||
Procedure: combo(IN emp_id, OUT tax_amount) READS SQL DATA DYNAMIC RESULT SETS 1, opens a cursor
|
||||
AND sets the OUT parameter.
|
||||
|
||||
Reading the OUT parameter BEFORE consuming the ResultSet:
|
||||
execute()=false
|
||||
OUT tax_amount = 7500.00 <- succeeds, no exception
|
||||
(then) getResultSet() still returns the cursor with its rows intact
|
||||
(then) OUT tax_amount read AGAIN = 7500.00 <- still succeeds
|
||||
|
||||
Reading the OUT parameter AFTER fully consuming the ResultSet:
|
||||
rows consumed first
|
||||
OUT tax_amount = 9000.00 <- also succeeds
|
||||
|
||||
CONCLUSION: unlike some JDBC drivers (historically SQL Server's, and some Oracle configurations)
|
||||
that require a stored procedure's result set(s) to be fully consumed before OUT parameters
|
||||
become readable, HSQLDB 2.7.3's driver imposes NO such ordering constraint. Reading the OUT
|
||||
value before, interleaved with, or after draining the cursor all work identically. The
|
||||
"ordering trap" described in stored-procedure folklore is real on SOME databases/drivers but
|
||||
is NOT reproducible on HSQLDB -- worth stating explicitly rather than assuming it's universal.
|
||||
Reference in New Issue
Block a user