Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Repository files navigation

ph-db

Sonatype Central javadoc

If this project saved you some time or made your day a little easier, a star would mean a lot — it helps others find it too.

Java library with some common DB API, a special JDBC version and a JPA version based on EclipseLink.

Licensed under the Apache 2.0 license.

Maven usage

Add the following to your pom.xml to use this artifact, where x.y.z is to be replaced with the last released version:

<dependency>
  <groupId>com.helger.db</groupId>
  <artifactId>ph-db-api</artifactId>
  <version>x.y.z</version>
</dependency>
<dependency>
  <groupId>com.helger.db</groupId>
  <artifactId>ph-db-jdbc</artifactId>
  <version>x.y.z</version>
</dependency>
<dependency>
  <groupId>com.helger.db</groupId>
  <artifactId>ph-db-jpa</artifactId>
  <version>x.y.z</version>
</dependency>
<dependency>
  <groupId>com.helger.db</groupId>
  <artifactId>ph-db-flyway</artifactId>
  <version>x.y.z</version>
</dependency>

Note: prior to v8.0.0 the group ID was com.helger

Telemetry

All three implementation modules emit vendor neutral telemetry through the ph-telemetry facades Telemetry (tracing) and TelemetryMetrics (metrics). Without a registered ITelemetryTracerSPI / ITelemetryMeterSPI, every span and every instrument degrades to a cheap no-op - so a deployment without an observability backend pays (almost) nothing. To get real data, add ph-telemetry-otel (or any other SPI implementation) to your application and register it via META-INF/services.

All emitted names are constants of CDBTelemetry in ph-db-api, so dashboards, alerting rules and tests can reference the literally same strings. Where the OpenTelemetry database semantic conventions define a name, that name is used verbatim (db.query.text, db.operation.name, db.response.returned_rows, db.system.name, db.namespace, error.type and the db.client.operation.duration instrument) - everything else is namespaced with phdb.. Note that the value of db.system.name is the ph-db EDatabaseSystemType ID (db2, h2, mysql, oracle, postgresql, sqlserver).

All duration instruments record seconds, because that is the unit the stable db.client.operation.duration convention prescribes.

Spans

Span Emitted by Notes
SELECT / INSERT / ... (db.query as fallback) DBExecutor one span per executed statement; the span name is the SQL operation
phdb.jdbc.transaction DBExecutor.performInTransaction one span per transaction level, with phdb.jdbc.transaction.outcome = committed, rolled-back or nested
phdb.jpa.transaction JPAEnabledManager.doInTransaction
phdb.jpa.select JPAEnabledManager.doSelect / doSelectStatic
phdb.flyway.migrate FlywayMigrationRunner.runFlyway one span per migration run

Metrics

Instrument Type Unit
db.client.operation.duration Histogram s
phdb.jdbc.statements Counter {statement}
phdb.jdbc.transactions Counter {transaction}
phdb.jdbc.connections Counter {connection}
phdb.jdbc.connections.active UpDownCounter {connection}
phdb.jdbc.connection.acquire.duration Histogram s
phdb.jpa.operations Counter {operation}
phdb.flyway.migrations Counter {migration}
phdb.flyway.migrate.duration Histogram s

Only bounded values are used as metric attributes - the SQL text is a span attribute only.

Configuration

DBExecutor does not know which database it talks to, so the db.system.name attribute is only emitted if it was provided:

aExecutor.setDatabaseSystemType (EDatabaseSystemType.POSTGRESQL);

The emission can be switched off per DBExecutor instance, and globally for all JPA operations:

// no spans and no metrics from this executor
aExecutor.setTelemetry (false);
// keep the spans, but never attach the SQL text
aExecutor.setTelemetrySQLText (false);
// no spans and no metrics from any JPAEnabledManager
JPAEnabledManager.setTelemetryEnabled (false);

Prepared statements only carry the parameterized SQL text, but the SQL passed to DBExecutor.executeStatement (String) and DBExecutor.queryAll (String) may contain literal values - use setTelemetrySQLText (false) if such values must not leave the process.

News and noteworthy

v8.5.0 - 2026-09-06

  • Added optional ph-telemetry support to ph-db-jdbc, ph-db-jpa and ph-db-flyway. Without a registered telemetry SPI, all emission degrades to cheap no-ops. DBExecutor emits a span per executed statement (named after the SQL operation, as the OpenTelemetry conventions demand), a span per transaction, and the metrics db.client.operation.duration, phdb.jdbc.statements, phdb.jdbc.transactions, phdb.jdbc.connections, phdb.jdbc.connections.active and phdb.jdbc.connection.acquire.duration. JPAEnabledManager emits a span per doInTransaction / doSelect plus the metrics db.client.operation.duration and phdb.jpa.operations. FlywayMigrationRunner emits a span per migration run plus the metrics phdb.flyway.migrations and phdb.flyway.migrate.duration. All emitted span, metric and attribute names are constants of the new class CDBTelemetry in ph-db-api. The OpenTelemetry database semantic conventions are followed where they define a name; everything else is namespaced with phdb.. All duration instruments use seconds as their unit, because db.client.operation.duration prescribes it.
  • Added DBExecutor.setDatabaseSystemType (EDatabaseSystemType) to provide the db.system.name telemetry attribute - the attribute is omitted if it is not set.
  • Added DBExecutor.setTelemetry (boolean) and DBExecutor.setTelemetrySQLText (boolean) as well as the static JPAEnabledManager.setTelemetryEnabled (boolean) to disable the telemetry emission. All of them default to enabled. Disable setTelemetrySQLText if the SQL passed to executeStatement or queryAll may contain literal values that must not leave the process - prepared statements only carry the parameterized SQL text anyway.
  • Fixed the transaction boundaries of DBExecutor.performInTransaction - thanks to @vinit-thummar for reporting and fixing it in issue #2. Every statement and every query executed inside a transaction committed the shared connection right after it was executed, so a later rollback could not undo the already committed work, and the intermediate states of a transaction became visible to concurrent readers on other connections. Commit and rollback now only happen at the outermost transaction boundary. Note that a failed SQL operation or a failed nested transaction now marks the whole transaction for rollback, even if the caller evaluates the returned ESuccess or the updated row count and continues instead of throwing - so a "try the insert, and on failure do the update instead" pattern no longer works inside a transaction, because no savepoints are used. As before, performInTransaction requires a connection with auto-commit disabled, and a nested performInTransaction joins the outer transaction instead of starting a new one. Because a connection with auto-commit enabled silently degrades a transaction to no transaction at all - every statement is committed on its own and the rollback has no effect - this case is now logged as an error when the outermost transaction is started.

v8.4.3 - 2026-09-03

  • Added the new overloads DBPagingHelper.getOrderByClause (IPagingSpec, IDBColumnNameResolver, Iterable) and getOrderByAndPagingClause (EDatabaseSystemType, IPagingSpec, IDBColumnNameResolver, Iterable), that take the default sort fields to be used if the paging specification contains no usable one - because none was requested, or because none could be resolved. Providing them is strongly recommended whenever the result is paged: without an ORDER BY a query returns the rows of a page in an undefined order, so that consecutive pages may overlap or lose rows. Contrary to the requested sort fields, which come from a client, the default sort fields come from the application and are therefore expected to be resolvable - an unresolvable default sort field is logged on the error level instead of the warning level.

v8.4.2 - 2026-08-30

  • Requires at least ph-commons 12.4.0
  • Added the new package com.helger.db.api.paging in ph-db-api, that creates the SQL clauses for a paged and sorted query from the data store independent IPagingSpec of ph-commons 12.4.0. DBPagingHelper.getPagingClause (EDatabaseSystemType, IPagingSpec) creates the database system specific clause to limit a query to a single page - LIMIT .. OFFSET .. for MySQL and the SQL standard OFFSET .. ROWS FETCH NEXT .. ROWS ONLY for DB2, H2, Oracle, PostgreSQL and SQL Server. "All rows starting at an offset" is supported as well; for MySQL it uses the documented workaround of a very large row count (DBPagingHelper.MYSQL_ALL_ROWS). DBPagingHelper.getOrderByClause (IPagingSpec, IDBColumnNameResolver) creates the matching ORDER BY clause, and getOrderByAndPagingClause (...) combines the two and warns if paging is applied without an order, because which rows a page contains is undefined that way. The new interface IDBColumnNameResolver maps the logical field name of a SortField onto the SQL column expression. It is the security boundary of the whole sorting: the field names typically originate from a UI and are therefore attacker controlled, while the returned expression ends up in the statement verbatim, because a column cannot be a JDBC parameter. Unknown field names are ignored, and IDBColumnNameResolver.createFromMap (Map) provides a whitelist based implementation. Note that a paging specification requesting 0 rows is rejected with an IllegalArgumentException, because there is no portable SQL for it - such a query should not be executed at all.

v8.4.1 - 2026-07-17

  • JdbcConfigurationConfig now logs the deprecation warning for a legacy *.millis/*.ms configuration key only once per key, instead of on every access.
  • Security: H2Helper.buildJDBCString now rejects connection property names containing ; or = and property values containing ;, preventing injection of additional H2 URL settings (e.g. INIT=RUNSCRIPT).
  • Security: AbstractGlobalEntityManagerFactory no longer includes the plaintext JDBC password in its IllegalStateException messages; the property map is now masked before being logged.
  • Security: added JDBCHelper.getMaskedConnectionString(String) which masks password=/pwd= values in a JDBC connection string. It is now applied when logging JDBC URLs in AbstractGlobalEntityManagerFactory, DataSourceProviderFromJdbcConfiguration and LoggingH2EventListener.
  • Extended IFlywayConfiguration with the validateOnMigrate flag (default false), configurable via FlywayConfigurationBuilderConfig key validate-on-migrate. Previously Flyway validation was unconditionally disabled.
  • DBExecutor now fails fast with an IllegalStateException if an instance that has an open transaction is used concurrently from another thread, instead of silently executing on the foreign transaction's connection.
  • Fixed ConnectionFromDataSource.setValidityCheckTimeoutSeconds clamping any positive timeout to 0; it now correctly keeps positive values and floors negatives at 0. The connection is now also closed when the validity check fails, avoiding a connection pool leak.
  • Fixed a NullPointerException in AbstractGlobalEntityManagerFactory when the optional additional factory properties map was null.

v8.4.0 - 2026-05-01

  • Updated to Flyway 12.5.0
  • IExecutionTimeExceededCallback.onExecutionTimeExceeded now takes Duration parameters (aExecutionDuration, aLimitDuration) instead of long milliseconds — breaking signature change. LoggingExecutionTimeExceededCallback was updated accordingly.
  • DBExecutor now stores the execution duration warning threshold as java.time.Duration internally. Added new primary setter setExecutionWarnDuration(Duration) and getter getExecutionWarnDuration(); the previously named setExecutionDurationWarn(Duration) / getExecutionDuration() / isExecutionDurationWarnEnabled() and the millis-based setExecutionDurationWarnMS(long) / getExecutionDurationWarnMS() are retained as @Deprecated(forRemoval = true) and delegate to the new methods. The new isExecutionWarnDurationEnabled() requires a strictly positive duration (> 0).
  • DBExecutor.onExecutionTimeExceeded(String, long) was changed to onExecutionTimeExceeded(String, Duration) to match the new callback signature.
  • JPAEnabledManager.onExecutionTimeExceeded(String, long) was changed to onExecutionTimeExceeded(String, Duration). Added new getDefaultExecutionWarnDuration() and setDefaultExecutionDuration(Duration) plus a DEFAULT_EXECUTION_WARN_DURATION constant; the existing getDefaultExecutionWarnTime(), setDefaultExecutionWarnTime(int) and DEFAULT_EXECUTION_WARN_TIME_MS are now @Deprecated(forRemoval = true).

v8.3.0 - 2026-05-01

  • Removed OSGI bundling
  • JdbcConfigurationConfig now accepts the duration grammar from ph-commons 12.2.5 (ConfigDurationParser) on five new configuration keys: execution-time-warning, pooling.max-wait, pooling.between-evictions-runs, pooling.min-evictable-idle, pooling.remove-abandoned-timeout. Values like 5s, 2m, 1h 30m are parsed to java.time.Duration. The legacy *.millis/*.ms keys remain supported for backward compatibility; the duration key wins when both are set, and a parse failure on the duration key falls back to the legacy key.
  • Added five java.time.Duration-typed accessors on IJdbcDataSourceConfiguration / IJdbcConfiguration: getJdbcPoolingMaxWait(), getJdbcPoolingBetweenEvictionRuns(), getJdbcPoolingMinEvictableIdle(), getJdbcPoolingRemoveAbandonedTimeout(), getJdbcExecutionTimeWarning(). The Duration getters are now the primary API; the existing getJdbc*Millis() long-millis getters are retained as @Deprecated thin wrappers.
  • JdbcConfiguration (POJO) now stores its five duration values as Duration internally. A new primary constructor accepts Duration parameters; the existing long-millis constructor is @Deprecated and delegates to it. Added matching DEFAULT_* Duration constants alongside the existing DEFAULT_*_MILLIS longs.
  • DataSourceProviderFromJdbcConfiguration now consumes the new Duration accessors directly, removing the Duration.ofMillis(...) wrappers around millis getters.
  • The legacy *.millis/*.ms configuration keys, the corresponding SUFFIX_*_MILLIS/SUFFIX_*_MS constants, the getConfigKey*Millis*() accessors, and the getJdbc*Millis() getters on IJdbcDataSourceConfiguration / IJdbcConfiguration / JdbcConfiguration / JdbcConfigurationConfig are now @Deprecated. A WARN-level log message is emitted at runtime when a legacy *.millis/*.ms configuration key is read, pointing at the new duration-grammar key.

v8.2.1 - 2026-04-12

  • Extended IJdbcDataSourceConfiguration, JdbcConfiguration and JdbcConfigurationConfig with the testOnBorrow pooling parameter

v8.2.0 - 2026-04-12

  • Added new submodule ph-db-flyway with FlywayMigrationRunner utility class for shared Flyway database migration setup
  • Moved Flyway configuration classes (FlywayConfiguration, FlywayConfigurationBuilderConfig, IFlywayConfiguration) from ph-db-api (com.helger.db.api.flyway) to ph-db-flyway (com.helger.db.flyway) — breaking package change
  • Extended IFlywayConfiguration with debugMode and repairMode flags

v8.1.3 - 2026-04-07

  • Extended IJdbcConfiguration, JdbcConfiguration and JdbcConfigurationConfig with connection pooling parameters: max connections, max wait, between eviction runs, min evictable idle, and remove abandoned timeout
  • DataSourceProviderFromJdbcConfiguration now directly handles the pooling parameter in a standard way
  • Added optional flywayHistoryTable parameter to IFlywayConfiguration for customizing the Flyway history table name

v8.1.2 - 2026-02-22

  • Updated to Apache Commons Pool 2.13.1
  • Updated to Apache Commons DBCP 2.14.0
  • Updated to EclipseLink 4.0.9
  • DBResultField constructor now takes an empty String as well
  • Renamed EDatabaseSystemType.MSSQL to SQLSERVER

v8.1.1 - 2025-12-10

  • Added specific support for Oracle Timestamp handling

v8.1.0 - 2025-11-16

  • Updated to ph-commons 12.1.0
  • Using JSpecify annotations

v8.0.1 - 2025-09-19

  • Added new class DBSystemHelper

v8.0.0 - 2025-08-25

  • Requires Java 17 as the minimum version
  • Updated to ph-commons 12.0.0
  • Updated to MySQLConnector/J 9.4.0
  • Changed the Maven group ID from com.helger to com.helger.db

v7.1.0 - 2025-04-11

  • Updated to Apache Commons Pool 2.12.1
  • Added new enum EDatabaseSystemType
  • Added new package com.helger.db.api.flyway
  • Added new package com.helger.db.api.config

v7.0.6 - 2024-09-20

  • Updated to Protobuf 4.28.2 to fix CVE-2024-7254

v7.0.5 - 2024-08-09

  • Updated to MySQLConnector/J 9.0.0
  • Updated to Protobuf 4.x

v7.0.4 - 2024-03-27

  • Updated to ph-commons 11.1.5
  • Updated to MySQLConnector/J 8.3.0
  • Updated to Apache Commons DBCP 2.12.0
  • Created Java 21 compatibility

v7.0.3 - 2023-12-10

  • Updated all dependencies

v7.0.2 - 2023-07-31

  • Updated to ph-commons 11.1

v7.0.1 - 2023-01-12

  • Updated to MySQLConnector/J 8.0.31 with new Maven coordinates
  • Updated to Protobuf 3.21.12

v7.0.0 - 2023-01-09

  • Using Java 11 as the baseline
  • Updated to ph-commons 11
  • Updated to EclipseLink 4.0.0

v6.7.4 - 2022-02-21

  • Updated to H2 2.0.210
  • Fixed a NullPointerException in CLOB handling

v6.7.3 - 2021-11-24

  • Updated to MySQLConnector/J 8.0.25
  • Added new class DBValueHelper
  • Added new class AbstractJDBCEnabledManager

v6.7.2 - 2021-09-19

  • Updated to Apache Commons Pool 2.11.1
  • Extended the DBExecutor API slightly

v6.7.1 - 2021-08-20

  • Updated to ph-commons 10.1
  • Updated to MySQLConnector/J 8.0.25
  • Updated to Apache Commons DBCP 2.9.0
  • Updated to Apache Commons Pool 2.10.0
  • Extended DBResultRow with additional methods

v6.7.0 - 2021-04-06

  • Added option to enabled/disable the connection state handling (and disabled it by default)

v6.6.0 - 2021-03-21

  • Updated to ph-commons 10
  • Updated to EclipseLink 2.7.8
  • Updated to MySQLConnector/J 8.0.23
  • Added new class ConnectionFromDataSource that has increased flexibility

v6.5.0 - 2020-11-27

  • Added conversion from CLOB to String - thanks to GG
  • Commented out the parameter check in favour of the default JDBC driver - thanks to GG for pointing that out
  • Removed the usage of Optional in the DBExecutor to more easily differentiate between "Error" and "Not found"

v6.4.0 - 2020-11-02

  • Updated to MySQLConnector/J 8.0.21
  • Improved debug logging in DBExecutor
  • Made DBExecutor consistently not thread-safe
  • Made some DBExectur methods static

v6.3.1 - 2020-09-30

  • Updated to Apache Commons Pool 2.9.0
  • Updated to Apache Commons DBCP 2.8.0

v6.3.0 - 2020-08-24

  • Renamed AbsractConnector to AbstractDBConnector
  • Removed AbstractDBConnector.getDatabaseName
  • Added class AbstractDBConnector
  • Dropped some specific connector implementations

v6.2.1 - 2020-08-20

  • Updated to EclipseLink 2.7.7
  • Updated to Apache Commons Pool 2.8.1
  • Updated DBResultRow API

v6.2.0 - 2020-04-23

  • Updated to Apache Commons Pool 2.8.0
  • Updated to MySQLConnector/J 8.0.19
  • Updated to EclipseLink 2.7.6
  • Extended JDBCHelper return types
  • Added simple transaction support in DBExecutor
  • Updated to ph-commons 9.4.1

v6.1.5 - 2019-10-25

  • Updated to Apache Commons Pool 2.7.0
  • Updated to Apache Commons DBCP 2.7.0
  • Updated to MySQLConnector/J 8.0.18
  • Updated to H2 1.4.200
  • Updated to EclipseLink 2.7.5
  • The EclipseLinkLogger logs all error levels below WARNING as Info

v6.1.4 - 2019-03-27

  • Updated to H2 1.4.199
  • Replacing "javax.persistence 2.2.1" with "jakarta.persistence 2.2.2"

v6.1.3 - 2019-03-12

  • Updated to EclipseLink 2.7.4
  • Updated to MySQLConnector/J 8.0.15
  • Updated to Apache Commons Pool 2.6.1
  • Updated to Apache Commons DBCP 2.6.0
  • Updated to H2 1.4.198

v6.1.2 - 2018-11-22

  • Updated to EclipseLink 2.7.3
  • Updated to MySQLConnector/J 8.0.13
  • Updated to ph-commons 9.2.0

v6.1.1 - 2018-07-24

  • Fixed OSGI ServiceProvider configuration
  • Updated to EclipseLink 2.7.2
  • Updated to Apache Commons DBCP 2.5.0
  • Updated to Apache Commons Pool 2.6.0
  • Catching an throwing Exception only (instead of Throwable)

v6.1.0 - 2018-04-23

  • Updated to Apache Commons DBCP 2.2.0
  • Updated to EclipseLink 2.7.1
  • JPAEnabledManager now has the possibility to disable the execution time warning

v6.0.0 - 2017-12-20

  • Updated to ph-commons 9.0.0
  • Updated to H2 1.4.196
  • Updated to EclipseLink 2.7.0
  • Updated to Apache Commons Pool2 2.5.0

v5.0.1 - 2016-08-21

  • Updated to ph-commons 8.4.x

v5.0.0 - 2016-06-11

  • Requires at least JDK8

My personal Coding Styleguide | It is appreciated if you star the GitHub project if you like it.

About

Java library with some basic DB API (neither JDBC nor JPA)

Resources

Code of conduct

Stars

0 stars

Watchers

1 watching

Forks

Releases

Packages

Used by

Contributors

Languages