I posted this on github but also cross posting it here.
I found you can accomplish a dynamic schema configuration for multiple schemas in different environments by overriding the physical naming strategy.
Let's say you have two entities like this which are configured for two different schemas -
@Entity
@Table(name="TABLE1", schema="schema1")
public class FooEntity implements Serializable {
...
}
@Entity
@Table(name="TABLE2", schema="schema2")
public class BarEntity implements Serializable {
...
}
First create a configuration in your application.yml file:
multischema:
config:
schema1: FIRSTSCHEMA
schema2: SECONDSCHEMA
Bind it to a ConfigurationProperties bean
@Component
@ConfigurationProperties("multischema")
public class MultiSchemaConfigurationProperties {
private Map<String,String> config;
public void setConfig(Map<String,String> config) {
this.config = config;
}
public Map<String,String> getConfig() {
return config;
}
}
Create a custom physical naming strategy which injects MultiSchemaConfigurationProperties and extends the Spring Boot default for your version. In this case I'm using Spring Boot 2.6.4 which uses CamelCaseToUnderscoresNamingStrategy.
@Component
public class MultiSchemaPhysicalNamingStrategy extends CamelCaseToUnderscoresNamingStrategy {
private final MultiSchemaConfigurationProperties schemaConfiguration;
public MultiSchemaPhysicalNamingStrategy(MultiSchemaConfigurationProperties schemaConfiguration) {
this.schemaConfiguration = schemaConfiguration;
}
@Override
public Identifier toPhysicalSchemaName(Identifier name, JdbcEnvironment jdbcEnvironment) {
if(name != null) {
Identifier identifier = super.getIdentifier(schemaConfiguration.getConfig()
.get(name.getText()), name.isQuoted(), jdbcEnvironment);
return super.toPhysicalSchemaName(identifier, jdbcEnvironment);
}
return name;
}
}
When the application starts up Hibernate will invoke the custom physical naming strategy to apply the physical naming rule for your schema using the provided configuration in application.yml. https://docs.spring.io/spring-boot/docs/current/reference/html/howto.html#howto.data-access.configure-hibernate-naming-strategy
"schema1" in FooEntity will be replaced by the value "firstschema" and "schema2" in BarEntity will be replaced by the value "secondschema".