Closed tjwatson closed 7 months ago
I had to move the env config for SPRING_JPA_PROPERTIES_HIBERNATE_TEMP_USE_JDBC_METADATA_DEFAULTS
to the application.yml
to get correct behavior when not using the onRefresh checkpoint:
hibernate.temp.use_jdbc_metadata_defaults: false
I updated the branch with the changes. It is unclear why the SPRING_JPA_PROPERTIES_HIBERNATE_TEMP_USE_JDBC_METADATA_DEFAULTS
env configuration isn't working. Perhaps the _
of the original property key causes issues when mapping to env keys?
This makes it work when not using onRefresh checkpoint. But if you change to using onRefresh checkpoint then the checkpoint appears to succeed without any connection to the data source. And the application does appear to restore successfully. But then when trying to connect to the /users
endpoint we still see org.postgresql.util.PSQLException: FATAL: password authentication failed for user "checkpointuser"
which indicates it is using the user credentials from the checkpoint and not the restore environment.
Hi, thanks for this repro, but I am not sure there is an actionable item for us on Spring Framework side.
After fixing a typo (double __
here), the following steps seems to work correctly thanks to your fix on the hibernate property:
./mvnbuild.sh docker
./checkpoint.sh docker
./restore-start.sh docker
I am not sure how and if hibernate.temp.use_jdbc_metadata_defaults
binding is supported to work as you seems to have followed the documented rules. May be worth an issue on Spring Boot side as this is a double special case (underscore in the property and coming from Hibernate directly).
The Canonical repository that @OlgaMaciaszek created for this use case is https://github.com/OlgaMaciaszek/crac-db-refresh-scope, you may be interested by the related documentation. And if there is an issue, that looks like more on Spring Cloud than Spring Framework.
As a consequence, I close this issue, but feel free to comment if you identify something we should fix and dig deeper on Spring Framework side.
@sdeleuze I needed to follow up with the expected behavior for when using the onRefresh checkpoint. When using onRefresh option I do not see the data source configuration options getting the values as configured from the resource side. It seems to keep using the config values as they were on the checkpoint side.
This seems unexpected. But I am not sure if that is an issue with Spring Cloud or something else in the spring framework that is expected to reflect the latest config from the restore side when using onRefresh so that components can get the right config when the context is refreshed on restore.
It seems to keep using the config values as they were on the checkpoint side
From the Spring Framework perspective, this is expected even if I can undertsand you are surprised. Any post checkpoint configuration update needs to be handled differently, potentially using Spring Cloud.
Thanks. I ask because I am trying to understand the scenarios where onRefresh
would be advised vs. doing a checkpoint after the application has fully started and letting the lifecycle beans and the other components from cloud refresh things like data sources as in the example at https://github.com/OlgaMaciaszek/crac-db-refresh-scope shows. But this is turning into more of a question answer session and likely should be discussed elsewhere. Thanks for your help.
I got this erreur 👍 java.lang.NullPointerException: Cannot invoke "org.hibernate.engine.jdbc.spi.SqlExceptionHelper.convert(java.sql.SQLException, String)" because the return value of "org.hibernate.resource.transaction.backend.jdbc.internal.JdbcIsolationDelegate.sqlExceptionHelper()" is null
@davysoul have you figured out some way to solve this
I had the same problem with this docker-compose.yml:
version: "3.9"
services: db: image: postgres:alpine restart: always env_file:
volumes: minio_storage: {}
I just replaced localhost in line ".. _URL" on db and everything worked: environment:
Also experiencing this... only when using oracle though, works fine with postgres
i be this error because url or username or password wrong
Apologize for the length of this write up.
Maybe related to #32299 but I believe I have the options all set correctly to do the checkpoint without having hibernate contact the remote database before checkpoint as desribed in https://github.com/spring-projects/spring-lifecycle-smoke-tests/tree/main/data/data-jpa.
Reproduction repo: https://github.com/tjwatson/crac-db-issue/tree/checkpointIssue
This is a modified version of https://github.com/OlgaMaciaszek/crac-db-sample
All scripts in here default to
podman
but you can passdocker
in if you want to use Docker insteadFirst build the Spring Boot application with:
./mvnbuild.sh docker
A docker compose file
docker-compose-checkpoint.yml
sets up the run for doing the checkpoint in container. This docker compose file sets the following to attempt to avoid connecting to the remote database before checkpoint by setting the environment values:Initially this file has the config
FLAG: '-r'
commented out. This flag is used to enable doing checkpoint on refresh. This docker compose file also has thedb
service commented out to demonstrate what happens at container image build when there is no database. Run the following to do the checkpoint (if using podman you must run as root or withsudo
):./checkpoint.sh docker
The following output should show the spring logs from the checkpoint:
Notice that there are errors trying to connect to
db
because there is no database running in the deployment during checkpoint. But the application proceeds to start anyway because theapplication.yml
has set:This does appear to restore fine if you run the
./restore-start.sh docker
command. This uses a separate docker compose filedocker-compose-restore.yml
which does enable thedb
service for the application to connect to. Running this script you see output like this:And this does appear to successfully connect to the
db
service if you browse http://localhost:8080/users (although thedb
service doesn't have an initialized database so you get errors likeERROR: relation "users" does not exist
but that is expected. Be sure to run./restore-stop.sh docker
to stop the services for the restore run.To try and avoid the connection to the database before the checkpoint there is the
FLAG
option that can be enabled indocker-compose-checkpoint.yml
by uncommenting the line withFLAG: '-r'
. If you then run./checkpoint.sh docker
again you will see the following:Notice it is still trying to connect to the database even when doing checkpoint on refresh. Then run
./restore-start.sh docker
to restore from this checkpoint:This does appear to restore, but I think the error that happened at checkpoint time prevents the restore from properly configuring the datasource because browsing http://localhost:8080/users now gets:
org.postgresql.util.PSQLException: FATAL: password authentication failed for user "checkpointuser"
which indicates it is using the user credentials from the checkpoint and not the restore environment.Finally, uncomment the
db
service indocker-compose-checkpoint.yml
and run./checkpoint.sh docker
again. You will see this error:That indicates that we have open connections to the
db
service when trying to checkpoint.