Add setReadOnly=false functionality on Connection class
- 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
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