In my spring boot application, the first migration creates a schema for the current user and switches to this schema. Subsequent migrations are properly executed on this schema. However, after migration is complete, these tables are not found by the application until the application is reloaded.
application.yml
spring:
r2dbc:
url: r2dbc:postgresql://127.0.0.1:5432/pickle_db
username: rick
password: morty
r2dbc:
migrate:
migrations-schema: public
migrations-table: fun_migrations
migrations-lock-table: fun_migrations_lock
resources-paths:
- classpath:/db/migration/*.sql
V1__schema.sql
CREATE SCHEMA IF NOT EXISTS fun;
ALTER ROLE current_user SET search_path TO 'fun';
SET search_path TO 'fun';
V2__tables.sql
CREATE TABLE TREE(id int, name varchar(64));
Migration runs successfully and creates following tables.
fun.tree
public.fun_migration
public.fun_migration_lock
2021-06-17 19:58:51.845 INFO 4400 --- [ restartedMain] n.n.r.m.a.R2dbcMigrateAutoConfiguration : Starting R2DBC migration
2021-06-17 19:58:51.847 INFO 4400 --- [ restartedMain] n.n.r2dbc.migrate.core.R2dbcMigrate : Configured with R2dbcMigrateProperties{enable=true, connectionMaxRetries=500, resourcesPaths=[classpath:/db/migration/*.sql], chunkSize=1000, dialect=null, validationQuery='select '42' as result', validationQueryExpectedResultValue='42', validationQueryTimeout=PT5S, validationRetryDelay=PT1S, acquireLockRetryDelay=PT1S, acquireLockMaxRetries=100, fileCharset=UTF-8, waitForDatabase=true, migrationsSchema='public', migrationsTable='fun_migrations', migrationsLockTable='fun_migrations_lock'}
2021-06-17 19:58:51.909 INFO 4400 --- [ restartedMain] n.n.r2dbc.migrate.core.R2dbcMigrate : Creating new test connection
2021-06-17 19:58:52.523 INFO 4400 --- [actor-tcp-nio-1] n.n.r2dbc.migrate.core.R2dbcMigrate : Comparing expected value '42' with provided result '42'
2021-06-17 19:58:52.525 INFO 4400 --- [actor-tcp-nio-1] n.n.r2dbc.migrate.core.R2dbcMigrate : Closing test connection
2021-06-17 19:58:52.532 INFO 4400 --- [actor-tcp-nio-1] n.n.r2dbc.migrate.core.R2dbcMigrate : Successfully got result '42' of test query
2021-06-17 19:58:52.678 INFO 4400 --- [actor-tcp-nio-1] n.n.r2dbc.migrate.core.R2dbcMigrate : By 'Making internal tables' 1 rows updated
2021-06-17 19:58:52.692 INFO 4400 --- [actor-tcp-nio-1] n.n.r2dbc.migrate.core.R2dbcMigrate : By 'Acquiring lock' 1 rows updated
2021-06-17 19:58:52.702 INFO 4400 --- [actor-tcp-nio-1] n.n.r2dbc.migrate.core.R2dbcMigrate : Database version is 0
2021-06-17 19:58:52.723 INFO 4400 --- [actor-tcp-nio-1] n.n.r2dbc.migrate.core.R2dbcMigrate : Applying MigrationInfo{version=1, description='schema', splitByLine=false, transactional=true}
2021-06-17 19:58:52.750 INFO 4400 --- [actor-tcp-nio-1] n.n.r2dbc.migrate.core.R2dbcMigrate : By 'MigrationInfo{version=1, description='schema', splitByLine=false, transactional=true}' 0 rows updated
2021-06-17 19:58:52.793 INFO 4400 --- [actor-tcp-nio-1] n.n.r2dbc.migrate.core.R2dbcMigrate : By 'Writing metadata version 1' 1 rows updated
2021-06-17 19:58:52.800 INFO 4400 --- [actor-tcp-nio-1] n.n.r2dbc.migrate.core.R2dbcMigrate : Applying MigrationInfo{version=2, description='tables', splitByLine=false, transactional=true}
2021-06-17 19:58:52.814 WARN 4400 --- [actor-tcp-nio-1] i.r.p.client.ReactorNettyClient : Notice: SEVERITY_LOCALIZED=NOTICE, SEVERITY_NON_LOCALIZED=NOTICE, CODE=00000, MESSAGE=table "tree" does not exist, skipping, FILE=tablecmds.c, LINE=1217, ROUTINE=DropErrorMsgNonExistent
2021-06-17 19:58:52.986 INFO 4400 --- [actor-tcp-nio-1] n.n.r2dbc.migrate.core.R2dbcMigrate : By 'MigrationInfo{version=2, description='tables', splitByLine=false, transactional=true}' 0 rows updated
2021-06-17 19:58:53.027 INFO 4400 --- [actor-tcp-nio-1] n.n.r2dbc.migrate.core.R2dbcMigrate : By 'Writing metadata version 2' 1 rows updated
2021-06-17 19:58:53.036 INFO 4400 --- [actor-tcp-nio-1] n.n.r2dbc.migrate.core.R2dbcMigrate : Applying MigrationInfo{version=3, description='data', splitByLine=false, transactional=true}
2021-06-17 19:58:53.058 INFO 4400 --- [actor-tcp-nio-1] n.n.r2dbc.migrate.core.R2dbcMigrate : By 'MigrationInfo{version=3, description='data', splitByLine=false, transactional=true}' 94 rows updated
2021-06-17 19:58:53.072 INFO 4400 --- [actor-tcp-nio-1] n.n.r2dbc.migrate.core.R2dbcMigrate : By 'Writing metadata version 3' 1 rows updated
2021-06-17 19:58:53.084 INFO 4400 --- [actor-tcp-nio-1] n.n.r2dbc.migrate.core.R2dbcMigrate : By 'Releasing lock' 1 rows updated
2021-06-17 19:58:53.090 INFO 4400 --- [ restartedMain] n.n.r.m.a.R2dbcMigrateAutoConfiguration : End of R2DBC migration
Once I connect to the application, I get following error.
postgresql log
database_1 | 2021-06-17 17:56:29.903 UTC [1] LOG: starting PostgreSQL 13.2 on x86_64-pc-linux-musl, compiled by gcc (Alpine 10.2.1_pre1) 10.2.1 20201203, 64-bit
database_1 | 2021-06-17 17:56:29.910 UTC [1] LOG: listening on IPv4 address "0.0.0.0", port 5432
database_1 | 2021-06-17 17:56:29.910 UTC [1] LOG: listening on IPv6 address "::", port 5432
database_1 | 2021-06-17 17:56:29.939 UTC [1] LOG: listening on Unix socket "/var/run/postgresql/.s.PGSQL.5432"
database_1 | 2021-06-17 17:56:29.960 UTC [51] LOG: database system was shut down at 2021-06-17 17:56:29 UTC
database_1 | 2021-06-17 17:56:29.972 UTC [1] LOG: database system is ready to accept connections
database_1 | 2021-06-17 18:03:52.818 UTC [65] ERROR: relation "tree" does not exist at character 15
database_1 | 2021-06-17 18:03:52.818 UTC [65] STATEMENT: SELECT * FROM TREE
After restarting the spring boot application, everything works perfectly fine. I assume, public.tree
, which does not exist, is selected before restart. Once the application is restarted, fun.tree
is selected. So, this happens only after this very first migration. How can I make the search_path
which is used during migration persistent? Alternatively, how would I reload the connection after the migration, such that the role defined search_path
is used?
Update 2021-06-18
I have found the reason for this issue. spring-boot-starter-data-r2dbc
pulls in io.r2dbc:r2dbc-pool
. Which creates 10 connections before ALTER ROLE current_user SET search_path TO 'fun';
is executed. SET search_path TO 'fun';
is only valid for the one session in which the migration runs.
So the question comes down to, how can I refresh all connections of the pool?