DatabaseExecutorImpl.javaPlain JDBC implementation of the DatabaseExecutor interface. 161 lines. IMPORTANT Javadoc warning: "DON'T USE THIS CLASS FOR PRODUCTION! This is only for demonstration purposes, because there is no connection pooling and connections may loose!!!!!" — this class is for Flyway migrations (which run before Hibernate is initialized), data patching scripts, and development/testing. Production code uses a JdbcTemplate-based implementation with HikariCP connection pooling.
Architecture: Every method creates an anonymous JdbcExecutor subclass (#638) that overrides the execute(PreparedStatement) template method. This is the Template Method pattern — JdbcExecutor handles connection lifecycle (open, set parameters, close), while each anonymous subclass provides the specific JDBC operation.
Method details:
execute(sql, ignoreErrors) — runs DDL/DML via stmt.execute(). Returns nothing. When ignoreErrors=true, JdbcExecutor catches SQLException and logs it at WARN level rather than rethrowing. Used for idempotent operations like DROP TABLE IF EXISTS.query(sql, args...) — the main query method. Creates a JdbcExecutor whose execute() override:
stmt.executeQuery() to get ResultSetwhile(rs.next()), creating one DatabaseResultRowImpl per rowResultSetMetaData columns (1-based → 0-based index conversion)DatabaseResultRowEntryImpl(type, name, value) for each columnList<DatabaseResultRow> — properly populated with column metadataResultSet is closed in a finally block — critical since this bypasses Hibernate's resource management.queryForInt(sql, args...) — returns single integer. Throws RuntimeException if result set is empty (no rs.next()). Used for SELECT COUNT(*) and similar aggregate queries. Closes ResultSet in finally.update(sql, args...) — executes stmt.executeUpdate(), returns the affected row count as Integer. Cast from Object — the generic JdbcExecutor template returns Object to accommodate different return types.Two constructors: DatabaseExecutorImpl() (no-arg — DataSource must be set later via setDataSource()) and DatabaseExecutorImpl(DataSource) (ready to use). The no-arg constructor exists for Spring XML configuration scenarios where DataSource is injected via property setter.
DataSource flow: The DataSource comes from Spring's @Bean DataSource (configured in application properties: spring.datasource.url, spring.datasource.username, spring.datasource.password). In production, this is a HikariCP pooled DataSource — but this class doesn't use pooling features. Its warning about "no connection pooling" refers to its own connection handling: each call to JdbcExecutor opens a new raw JDBC connection via DataSource.getConnection() rather than borrowing from the pool, which should still work with HikariCP but isn't the intended usage.
Dependencies: JdbcExecutor (#638), DatabaseResultRowImpl (#637), DatabaseResultRowEntryImpl (#636). All in the same jdbc sub-package.