Change database schema used by Spring Boot - java

How do I specify database schema used by Spring Boot? I am using default hibernate (=default) and postgres (but i hoping for a generic solution). I know how to specify JDBC URL:
spring.datasource.url=jdbc:postgresql:db_name
But unfortunately postgresql does not allow to specify schema in JDBC URL. I know that there is hibernate property hibernate.default_schema, so I was hoping that one of the following properties will work:
hibernate.default_schema=schema
spring.hibernate.default_schema=schema
spring.jpa.hibernate.default_schema=raw_page
But unfortunately neither of them seems to have any result.

Use for application.properties:
spring.jpa.properties.hibernate.default_schema=your_scheme
OR for application.yaml:
spring:
jpa:
properties:
hibernate.default_schema: your_scheme
From the Spring Boot reference guide:
all properties in spring.jpa.properties.* are passed through as normal JPA properties (with the prefix stripped) when the local EntityManagerFactory is created
See http://docs.spring.io/spring-boot/docs/current/reference/htmlsingle/#howto-configure-jpa-properties
For a full list of available properties see http://docs.spring.io/spring-boot/docs/current/reference/htmlsingle/#howto-configure-jpa-properties

It depends on the DataSource implementation which property has to be used to set the default schema (reference). With HikariDataSource for example spring.jpa.properties.hibernate.default_schema is ignored and you have to set
spring.datasource.hikari.schema=schema
See the complete list of HikariCP configuration parameters here.

spring.jpa.properties.hibernate.default_schema=your_scheme
OR
spring:
jpa:
properties:
hibernate.default_schema: your_scheme
With HikariDataSource for example spring.jpa.properties.hibernate.default_schema is ignored and you have to set too
spring.datasource.hikari.schema=your_scheme

spring:
jpa:
properties:
hibernate:
default_schema: your_schema_name

I was hitting error:
Cannot acquire connection from data source
org.postgresql.util.PSQLException: ERROR: unsupported startup parameter: search_path
Solution:
application-xyz_dev.yml
url: jdbc:postgresql://localhost:8080/your_database?search_path=your_scheme&stringtype=unspecified
spring:
jpa:
properties:
hibernate.default_schema: your_scheme

Related

spring.datasource.data picked up, but script never executed

I am trying to set up in-memory H2 tables for a test class in my Spring boot application.
My config looks something like:
spring:
jpa:
show-sql: true
generate-ddl: true
properties:
hibernate:
dialect: org.hibernate.dialect.H2Dialect
hibernate:
ddl-auto: create-drop
datasource:
# not sure which one to use so added both just in case
initialization-mode: always
initialize: true
platform: h2
# casting a wide net here, but no cookie - completely ignored
data: data-h2.sql,classpath*:data-h2.sql, classpath:data-h2.sql
url: jdbc:h2:mem:test;DB_CLOSE_DELAY=-1;DB_CLOSE_ON_EXIT=FALSE
driver-class-name: org.h2.Driver
username: sa
password:
As you can see, I'm trying to load a data-h2.sql script upon db initialization.
Unfortunately, the property is ignored no matter the value.
I am certain the configuration file is being picked up properly (e.g. among others, I desperately added a #Value("${spring.datasource.data}" -annotated property in my test class and the value was indeed populated correctly).
As an alternative, I could annotate the test class with #Sql("classpath:data-h2.sql") which did run the script - however it did so for every test, while I wanted the script to be run once before any test execution.
I also tried removing that and using a blank schema.sql and moving the population to data.sql (as suggested here), but Spring would complain about the empty schema file - which is useless to me, because my schema is auto-generated and I certainly don't want to re-create it (NB: probably a conflict with a hibernate property if memory serves).
I've browsed some of the answers here, but the only one I could use, is not working.
The only solution I can see is to keep the #Sql annotation, but try and clear the tables after every test with another #Sql annotation launching another script on #After.
This seems insane to me - there must be a better solution.
Am I missing something more esoteric than it already is in my configuration?
Simply put your file in the /main/resources directory (what you already did)
Spring Boot 2:
The correct property is:
spring.datasource.initialization-mode=always
Read more about this topic in the Spring Boot Documentation: https://docs.spring.io/spring-boot/docs/current/reference/htmlsingle/#howto-initialize-a-database-using-spring-jdbc
Spring Boot 1
You only have to place data-h2.sql in the classpath
Read more about this topic in the Spring Boot Documentation:
https://docs.spring.io/spring-boot/docs/1.5.8.RELEASE/reference/htmlsingle/#howto-initialize-a-database-using-spring-jdbc

How to cause SpringBoot/Hibernate to create a schema for unit testing?

Environment
SpringBoot 2 with H2 as test dependency.
Production works
Jar is deployed to cloud. A DB2 service is configured with driver and connection details, and automatically bound to the java application. There's no configuration in the jar itself. There is the application.properties file but it's empty. This part works fine and I'm hoping that a solution exists which will not require me to create property files and profiles.
Local Unit Test crashes on 'schema xxx not found'
#Entity(table="Employee", schema="acme")
class Employee {
...
}
#RunWith(SpringRunner.class)
#DataJpaTest
public class EmployeeTest {
...
}
No data source configuration exists.
SpringBoot sees H2 dependency and selects Hibernate by default.
Hibernate sees the Entity definition and attempts to drop the table first.
The drop uses the schema name drop table acme.employee if exists. No schema has been created so process fails with JdbcSQLSyntaxErrorException: Schema "acme" not found.
I tried #TestPropertySource(properties ="jdbc:h2:testb;INIT=CREATE SCHEMA IF NOT EXISTS acme;") with no luck.
I've found issues like this on the web and potential solutions. But they go very far into Hibernate and/or Spring configuration files. I would really want to avoid this. It's only local unit test that fails so I'm hoping to find a solution that is contained within the test.
If you need a different behaviour for your tests, that's basically a different profile. Although you prefer not to define properties files, the solution below doesn't go too deep into configuration and allows you to be very explicit in your tests.
Create application-test.properties (or yml if you prefer) with:
spring.datasource.url = jdbc:h2:mem:testb;init=CREATE SCHEMA IF NOT EXISTS acme;
Select Spring profile in your test classes with the annotation #ActiveProfiles:
#SpringBootTest
#ActiveProfiles("test")
class MyTest {
...
}
Give it a go. H2 should create the schema just before Hibernate tries to create the tables.
The absolute simplest means of doing this is to use h2 (or hsql as you are), and set ddl-auto to create-drop.
spring:
datasource:
driver-class-name: org.h2.Driver
password:
url: jdbc:h2:acme
username: sa
jpa:
database-platform: org.hibernate.dialect.H2Dialect
hibernate:
ddl-auto: create-drop

Send application name when connecting to an Oracle DB using HikariCP in Spring

I have a Spring Boot 1.4.7 application that I am currently updating to version 2.0.5. The application connects to an Oracle DB using JDBC using the following configuration:
spring:
jpa:
database-platform: org.hibernate.dialect.Oracle12cDialect
datasource:
url: jdbc:oracle:thin:#<db_server>
username: ${credentials.database.username}
password: ${credentials.database.password}
driver-class: oracle.jdbc.OracleDriver.class
platform: oracle
tomcat:
connection-properties: v$session.program=${spring.application.name}
After updating the application to Spring Boot 2.0.5 the application name sent to the server is JDBC Thin Client instead of ${spring.application.name}. The reason for this seems to be the switch to HikariCP as the default connection pool in Spring 2.x. How would I migrate this configuration to Hikari in a way that allows me to send a custom property for v$session.program to the db?
What I have tried:
Appending ?ApplicationName=<name> to the JDBC url.
Solutions mentioned in this Stackoverflow question
Setting System.setProperty("oracle.jdbc.v$session.program", <name>)
Setting spring.datasource.hikari.data-source-properties.v$session.program: <name> in the application.yml
In yaml, the dollar sign is escaped.
spring.datasource.hikari.data-source-properties.v$session.program: <name>
com.zaxxer.hikari.HikariConfig : dataSourceProperties............{password=<masked>, vsession.program=<name>}
Try this.
spring:
datasource:
hikari:
data-source-properties: v$session.program=name
Using HikariCP pool properties (default pool in Spring Boot 2)
spring:
datasource:
hikari:
data-source-properties:
v$session.program: MyAppName
If you want to reference to spring.application.name you have to use it like this:
spring:
datasource:
hikari:
data-source-properties:
"[v$session.program]": ${spring.application.name}

Spring 1.4.0 release hibernate naming strategy will add underscore(_) to table and column names

I have upgraded my spring version from 1.3.6 to 1.4.0 and now when I try to access my controller and see the log it always fetches for table with _ added to camel case conversion.
I am using EJB3NamingStrategy as before but that is not helpful here.
Here is how my application.yml looks
spring:
jpa:
hibernate:
naming:
strategy: org.hibernate.cfg.EJB3NamingStrategy
I used this and it worked.
spring.jpa.hibernate.naming.physical-strategy=org.hibernate.boot.model.naming.PhysicalNamingStrategyStandardImpl

Spring Boot - How to set the default schema for PostgreSQL?

What I am currently doing in my application.properties file is:
spring.datasource.url=jdbc:postgresql://localhost:5432/myDB?currentSchema=mySchema
Isn't there another property for this? Since it looks hacky and according to a post (still finding the link sorry, will update later), it is only applicable to PostgreSQL 9.4.
Since this is quite old and has no proper answer yet, the right property to set is the following:
spring.jpa.properties.hibernate.default_schema=yourschema
You can try setting the default schema for the jdbc user.
1)
ALTER USER user_name SET search_path to 'schema'
2) Did you try this property?
spring.datasource.schema
http://docs.spring.io/spring-boot/docs/current/reference/html/howto-database-initialization.html
With SpringBoot 2.5.5 the only thing that work for me:
aplication.properties
spring.datasource.hikari.schema=my_schema
aplication.yml version:
spring:
datasource:
hikari:
schema: my_schema

Categories

Resources