grails-data-hibernate7: request-session connection closes after a lazy load inside withNewSession
I maintainer di solito rispondono entro 1 giorno
Valutazione
- Difficoltà
- 4/5
- Tempo stimato
- 3-5 giorni
- Idoneità per principianti
- 32/100
- Tipo di issue
- Bug
- Chiarezza
- Abbastanza chiara
- Stato di attività
- Attiva
- Stack tecnologico
- groovy, mariadb, mysql
- Ambito
- database
Direzione di ricerca
The failure sits in the Hibernate session handling of grails-data-hibernate7, around executeWithNewSession and GrailsHibernateTemplate's exception conversion. Start by reproducing with the linked repro app (./gradlew bootRun, then curl /repro) and reading the JDBC log that precedes the NullPointerException. Done means the request session stays usable after withNewSession { withTransaction { ... } } and a regression spec covers the case.
Scritto dal modello di indicizzazione a partire dal testo della issue.
Descrizione
Expected Behavior
In this report, the request session is the Hibernate session that open session in view (OSIV) binds. The new session is the session that withNewSession opens. The inner transaction is the transaction that withTransaction starts in the new session.
After withNewSession { withTransaction { … } } completes, the OSIV-bound request session remains usable. Subsequent queries and refresh() succeed.
Actual Behaviour
Code runs in the request session without a transaction. It runs and ends a transaction on the request session. It then calls withNewSession { withTransaction { } }. Inside that block, it reads a lazy association of an entity that the request session loaded.
After the block, the next statement of the request session fails because its connection is closed. GrailsHibernateTemplate then throws a NullPointerException ("Cannot throw exception because the return value of ... convertHibernateAccessException(...) is null"). Before the NullPointerException, the log shows the JDBC error. On H2, the error is The object is already closed [90007-240].
Steps To Reproduce
- Clone https://github.com/homicki/grails8-withnewsession-closed-connection-repro and run
./gradlew bootRun. curl -i http://localhost:8080/reproreturns500with theNullPointerExceptionabove.curl -i "http://localhost:8080/repro?lazyLoad=before"returns200. This control reads the association before the block.
The action runs in the OSIV request session without a transaction. BootStrap seeds one book and its author, and Book.author is lazy:
Book book = Book.first()
Author.withTransaction { Author.count() } // ends a transaction on the request session
Book.withNewSession {
Book.withTransaction {
book.author.name // lazy load through the request session
new Author(name: 'Tenar').save()
}
}
Book.count() // fails: the connection is closed
The reproduction fails when all three of these conditions are true: a transaction ended on the request session earlier, the first use of the request session after that transaction is inside the inner transaction, and the inner block uses withNewSession. In the tested variants, withNewTransaction alone succeeds, and loading the association before or after the block also succeeds.
Proposed fix: before executeWithNewSession unbinds the request session, make an open, disconnected request session get its own connection. I have this fix with a spec that fails without it and passes with it, written with AI assistance. If the team agrees with this approach, I can submit it as a pull request.
Environment Information
- Grails 8.0.x
- Hibernate ORM 7.4
- Spring Framework 7.0
- MariaDB 10.11 and MySQL 8.4
- Groovy 5.1
- JDK 25
Example Application
https://github.com/homicki/grails8-withnewsession-closed-connection-repro
Version
8.0.0
- Lingua principale
- Groovy
- Stelle
- 2.9k
- Fork
- 980
- Merge medio
- 1g 17h
- PR unite (30g)
- 192
Preparare l'ambiente
- Nessun Dockerfile né file Docker Compose
- Ha un modello di pull request
- Leggi la guida per i contributori
Come iniziare
- Leggi tutta la issue e poi la guida ai contributi del progetto.
- Commenta sulla issue per dire che te ne occupi tu — evita che due persone facciano lo stesso lavoro.
- Fai un fork del repository e lavora su un branch.
- Apri una pull request che faccia riferimento al numero della issue.
Altre issue di apache/grails-core
-
Difficoltà 2/5 1-3 ore Idoneità per principianti 78/100
apache/grails-core#16289 · 5 commenti ·
I maintainer di solito rispondono entro 1 giorno
-
Difficoltà 2/5 1-3 ore Idoneità per principianti 82/100
apache/grails-core#15764 ·
I maintainer di solito rispondono entro 1 giorno
-
Update documentation for Java 25Forse già presa @ruthst00 l’ha presa 26 giorni fa. Apertarelates-to: documentation weekly-action-item
Difficoltà 2/5 1-3 ore Idoneità per principianti 68/100
apache/grails-core#15725 ·
I maintainer di solito rispondono entro 1 giorno
-
Hibernate 7: Criteria projection immutability, fail-fast unresolved paths, and inList null handlingForse già presa Una pull request collegata a questa issue è aperta o già unita. Apertarelates-to: gorm type: bug
Difficoltà 4/5 3-5 giorni Idoneità per principianti 55/100
apache/grails-core#16815 · 1 commento ·
I maintainer di solito rispondono entro 1 giorno
-
Datastore: Thread-safe deferred criteria (whereLazy) materialization on copiesForse già presa Una pull request collegata a questa issue è aperta o già unita. Apertarelates-to: gorm type: bug
Difficoltà 4/5 3-5 giorni Idoneità per principianti 45/100
apache/grails-core#16814 · 1 commento ·
I maintainer di solito rispondono entro 1 giorno
Tutte le issue di apache/grails-core
Issue simili
-
Difficoltà 2/5 1-3 ore Idoneità per principianti 66/100
microsoft/agent-framework#9946 ·
I maintainer di solito rispondono entro 1 giorno
-
Difficoltà 2/5 Mezza giornata Idoneità per principianti 62/100
rmax/scrapy-redis#337 ·
-
Advanced search: created_at:!= combined with another term returns entries that do not match itAperta
Difficoltà 2/5 1-3 ore Idoneità per principianti 75/100
I maintainer di solito rispondono entro 1 giorno
-
Index conflicts report and internal errorForse già presa Una pull request collegata a questa issue è aperta o già unita. Apertatriage
Difficoltà 2/5 1-3 ore Idoneità per principianti 72/100
I maintainer di solito rispondono entro 2 giorni
-
bug
Difficoltà 2/5 1-3 ore Idoneità per principianti 72/100
chriskelly/wish-together#102 ·
I maintainer di solito rispondono entro 1 giorno