bloomberg / bloomberg/comdb2

Add setReadOnly=false functionality on Connection class

Open
#6,012 1 comment 0 reactions 0 assignees View on GitHub
Dominant language
C
Stars
1.5k
Forks
243
Avg merge
2d 2h
Merged PRs (30d)
37

Description

**Is your feature request related to a problem? Please describe.**
When working with Hibernate/Spring JPA, sometimes the connection is set to read-only since SimpleJpaRepository is readOnly=true by default. This leads to errors when later trying to do writes
```
o.s.j.d.DataSourceUtils [task-1] - Setting JDBC Connection [HikariProxyConnection@210385308 wrapping com.bloomberg.comdb2.jdbc.Comdb2Connection@794d28a3] read-only
...
DEBUG o.s.j.d.DataSourceUtils [task-1] - Resetting read-only flag of JDBC Connection [HikariProxyConnection@210385308 wrapping com.bloomberg.comdb2.jdbc.Comdb2Connection@794d28a3]
...
2026-06-05 13:36:35.215 INFO o.h.orm.jdbc.batch [task-1] - HHH100503: On release of batch it still contained JDBC statements
2026-06-05 13:36:35.215 DEBUG o.h.e.j.s.SqlExceptionHelper [task-1] - could not execute batch [insert into attribute_hash_registry (attribute_data,attribute_source,created_at,created_by,source_id,attribute_hash) values (?,?,?,?,?,?)] java.sql.SQLNonTransientException: [RC = -21] connection/database in read-only mode at com.bloomberg.comdb2.jdbc.Comdb2Connection.createSQLException(Comdb2Connection.java:758) at com.bloomberg.comdb2.jdbc.Comdb2Statement.executeQuery(Comdb2Statement.java:141) at com.bloomberg.comdb2.jdbc.Comdb2Statement.executeQuery(Comdb2Statement.java:73) at com.bloomberg.comdb2.jdbc.Comdb2Statement.executeUpdate(Comdb2Statement.java:165) at com.bloomberg.comdb2.jdbc.Comdb2PreparedStatement.executeUpdate(Comdb2PreparedStatement.java:84) at com.bloomberg.comdb2.jdbc.Comdb2PreparedStatement.executeBatch(Comdb2PreparedStatement.java:380) at com.zaxxer.hikari.pool.ProxyStatement.executeBatch(ProxyStatement.java:128) at com.zaxxer.hikari.pool.HikariProxyPreparedStatement.executeBatch(HikariProxyPreparedStatement.java) at org.hibernate.engine.jdbc.batch.internal.BatchImpl.lambda$performExecution$2(BatchImpl.java:279) at org.hibernate.engine.jdbc.mutation.internal.PreparedStatementGroupSingleTable.forEachStatement(PreparedStatementGroupSingleTable.java:67) at org.hibernate.engine.jdbc.batch.internal.BatchImpl.performExecution(BatchImpl.java:264) at org.hibernate.engine.jdbc.batch.internal.BatchImpl.execute(BatchImpl.java:242) at org.hibernate.engine.jdbc.internal.JdbcCoordinatorImpl.executeBatch(JdbcCoordinatorImpl.java:188) at org.hibernate.engine.spi.ActionQueue.executeActions(ActionQueue.java:674) at org.hibernate.engine.spi.ActionQueue.executeActions(ActionQueue.java:511) at org.hibernate.event.internal.AbstractFlushingEventListener.performExecutions(AbstractFlushingEventListener.java:414) at org.hibernate.event.internal.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:41) at org.hibernate.event.service.internal.EventListenerGroupImpl.fireEventOnEachListener(EventListenerGroupImpl.java:127) at org.hibernate.internal.SessionImpl.doFlush(SessionImpl.java:1429) at org.hibernate.internal.SessionImpl.managedFlush(SessionImpl.java:491) at org.hibernate.internal.SessionImpl.flushBeforeTransactionCompletion(SessionImpl.java:2354) at org.hibernate.internal.SessionImpl.beforeTransactionCompletion(SessionImpl.java:1978) at org.hibernate.engine.jdbc.internal.JdbcCoordinatorImpl.beforeTransactionCompletion(JdbcCoordinatorImpl.java:439) at org.hibernate.resource.transaction.backend.jdbc.internal.JdbcResourceLocalTransactionCoordinatorImpl.beforeCompletionCallback(JdbcResourceLocalTransactionCoordinatorImpl.java:169) at org.hibernate.resource.transaction.backend.jdbc.internal.JdbcResourceLocalTransactionCoordinatorImpl$TransactionDriverControlImpl.commit(JdbcResourceLocalTransactionCoordinatorImpl.java:267) at org.hibernate.engine.transaction.internal.TransactionImpl.commit(TransactionImpl.java:101) at org.springframework.orm.jpa.JpaTransactionManager.doCommit(JpaTransactionManager.java:563) at org.springframework.transaction.support.AbstractPlatformTransactionManager.processCommit(AbstractPlatformTransactionManager.java:795) at org.springframework.transaction.support.AbstractPlatformTransactionManager.commit(AbstractPlatformTransactionManager.java:758) at org.springframework.transaction.interceptor.TransactionAspectSupport.commitTransactionAfterReturning(TransactionAspectSupport.java:698) at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:416) at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:119) at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:184) at ...
```

The "resetting" log line shows that `con.setReadOnly(false)` is called, but the later write still fails because of this read-only error.

**Describe the solution you'd like**
Add functionality to support `setReadOnly(false)` i.e. enable writes on the connection as well.
Example from Postgres
https://github.com/pgjdbc/pgjdbc/blob/ffe5827abfcb538cb8651b484674ade936286bef/pgjdbc/src/main/java/org/postgresql/jdbc/PgConnection.java#L931

**Describe alternatives you've considered**
In Java applications, you could create a new base repository class with `@Transactional(readOnly=false)` instead of using SimpleJpaRepository, but this is just inconvenient compared to the Comdb2 connection supporting enabling writes on the connection. Also, you would only do that if you knew this issue existed. In this case, I didn't and had to investigate to come up with this workaround

Contributor guide

Open the contributing guide

Research direction

Start at the Connection class and trace how JDBC read-only state changes are handled, using the linked PostgreSQL PgConnection implementation as a reference. Verify that calling setReadOnly(false) enables subsequent writes in the Hibernate/Spring JPA scenario described, and add or run the relevant connection tests if the project provides them.

Written by the indexing model from the issue text.

Assessment

Tech stack
java, sql
Domain
databases
Issue type
Feature
Difficulty
3/5
Estimated time
1-2 days
Activity status
Quiet
Clarity
Mostly clear
Newbie friendliness
52/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.