micronaut-projects / micronaut-projects/micronaut-data
generated CrudRepository finder fails on setting connection read-only on postgres DB
- Dominant language
- Java
- Stars
- 482
- Forks
- 229
- Avg merge
- 1d 7h
- Merged PRs (30d)
- 32
Description
### Expected Behavior
An auto-implemented read-only method (e. g. findById) should create a read-only transaction by default without throwing an exception.
### Actual Behaviour
The auto-implemented method first creates a connection then tries to modify it to read-only later, which the postgres driver rejects. Stacktrace:
```
Could not set JDBC Connection [HikariProxyConnection@625868084 wrapping org.postgresql.jdbc.PgConnection@7262532a] read-only: Cannot change transaction read-only property in the middle of a transaction.
io.micronaut.data.connection.exceptions.ConnectionException: Could not set JDBC Connection [HikariProxyConnection@625868084 wrapping org.postgresql.jdbc.PgConnection@7262532a] read-only: Cannot change transaction read-only property in the middle of a transaction.
at app//io.micronaut.data.connection.support.JdbcConnectionUtils.setConnectionReadOnly(JdbcConnectionUtils.java:170)
at app//io.micronaut.data.connection.support.JdbcConnectionUtils.applyReadOnly(JdbcConnectionUtils.java:75)
at app//io.micronaut.data.connection.jdbc.operations.DefaultDataSourceConnectionOperations.lambda$setupConnection$0(DefaultDataSourceConnectionOperations.java:67)
at java.base@17.0.7/java.util.Optional.ifPresent(Optional.java:178)
at app//io.micronaut.data.connection.jdbc.operations.DefaultDataSourceConnectionOperations.setupConnection(DefaultDataSourceConnectionOperations.java:65)
at app//io.micronaut.data.connection.support.AbstractConnectionOperations.executeWithNewConnection(AbstractConnectionOperations.java:142)
at app//io.micronaut.data.connection.support.AbstractConnectionOperations.execute(AbstractConnectionOperations.java:90)
at app//io.micronaut.data.connection.ConnectionOperations.executeRead(ConnectionOperations.java:71)
at app//io.micronaut.data.jdbc.operations.DefaultJdbcRepositoryOperations.executeRead(DefaultJdbcRepositoryOperations.java:765)
at app//io.micronaut.data.jdbc.operations.DefaultJdbcRepositoryOperations.findOne(DefaultJdbcRepositoryOperations.java:310)
at app//io.micronaut.data.runtime.intercept.DefaultFindOptionalInterceptor.intercept(DefaultFindOptionalInterceptor.java:47)
at app//io.micronaut.data.runtime.intercept.DefaultFindOptionalInterceptor.intercept(DefaultFindOptionalInterceptor.java:34)
at app//io.micronaut.data.runtime.intercept.DataIntroductionAdvice.intercept(DataIntroductionAdvice.java:83)
at app//io.micronaut.aop.chain.MethodInterceptorChain.proceed(MethodInterceptorChain.java:137)
...
Caused by: org.postgresql.util.PSQLException: Cannot change transaction read-only property in the middle of a transaction.
at app//org.postgresql.jdbc.PgConnection.setReadOnly(PgConnection.java:897)
at app//com.zaxxer.hikari.pool.ProxyConnection.setReadOnly(ProxyConnection.java:410)
at app//com.zaxxer.hikari.pool.HikariProxyConnection.setReadOnly(HikariProxyConnection.java)
at app//io.micronaut.data.connection.support.JdbcConnectionUtils.setConnectionReadOnly(JdbcConnectionUtils.java:167)
... 23 more
```
In Micronaut 3 this was swallowed (not great, either, we didn't notice).
### Steps To Reproduce
1. Have a Postgres DB with a simple table
2. Write a CrudRepository that extends io.micronaut.data.repository.CrudRepository using `@JdbcRepository(dialect = Dialect.POSTGRES)`
3. Set `datasources.default.auto-commit=false` in the application.properties
4. Call `repo.findById()` in a `@MicronautTest(transactional=false)`
### Environment Information
OS: MacOS VEntura 13.4.1
Java: 17
### Example Application
_No response_
### Version
4.0.1
Contributor guide
Research direction
Start by reproducing the CrudRepository findById call with PostgreSQL, auto-commit=false, and @MicronautTest(transactional=false). Read JdbcConnectionUtils and DefaultDataSourceConnectionOperations around the stack-trace lines, then trace ConnectionOperations.executeRead. Done means the generated read-only finder completes without PostgreSQL rejecting the transaction read-only setting.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- java, postgresql
- Domain
- backend, databases
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 42/100