How to configure schema for R2DBC PostgreSQL - java

I try to use Spring Data R2DBC with postgres.
I know some configuration for url, username, password.
spring.r2dbc.url
spring.r2dbc.username
spring.r2dbc.password
Is there something for the schema?
Any list of setting available?

Schema is Postgres-specific and can be configured through the R2DBC Connection URL:
r2dbc:postgresql://<server>:<port>/<database>?schema=<yourSchema>
See also:
Documentation

More pretty way to pass schema in properties:
in yaml format:
spring:
r2dbc:
properties:
schema: <yourSchema>
or properties format:
spring.r2dbc.properties.schema: <yourSchema>

Related

Mapping of JDBC connection string parameters to MyBatis properties

I am using mybatis-guice (MyBatisModule) to connect the Java application with the PostgreSQL database.
The connection parameters are sent to MyBatis as named properties (see an example here: https://mybatis.org/guice/jdbc-helper.html)
The MyBatis properties corresponding to the JDBC connection string postgresql://localhost/mydb?user=me&password=secret are:
final Properties properties = new Properties();
properties.setProperty("JDBC.host", "localhost");
properties.setProperty("JDBC.schema", "mydb");
properties.setProperty("JDBC.username", "me");
properties.setProperty("JDBC.password", "secret");
Names.bindProperties(binder, properties);
How to send other parameters of JDBC connection string to MyBatis?
For example, I need to use the following connection string: postgresql://localhost/mydb?user=me&password=secret&prepareThreshold=0, how could I send the attribute prepareThreshold=0 to MyBatis?
Following an example in the MyBatis docs, I tried to use
properties.setProperty("JDBC.prepareThreshold", "0");
but apparently it doesn't work.
Is it possible to use miscellaneous JDBC connection string parameters like prepareThreshold in the MyBatis Guice module?

Spring Data JPA, Hibernate #Table

I have a problem:
My application has an MSSQL host in which there are 2 databases.
All my entities look at base number:
And one Entity should look at base
I can do this by specifying the base in the #Table parameter (schema = databasename.schema)
Is there any way to make the #Table (schema) parameter come from application.properties?
Yes, it is possible. Look at the following properties:
<property name="hibernate.default_catalog" value="crm"/>
<property name="hibernate.default_schema" value="analytics"/>
You can use the following properties in the spring boot application.properties:
spring.jpa.properties.hibernate.default_catalog=crm
spring.jpa.properties.hibernate.default_schema=analytics
Look also at the #Table annotation documentation. When you set the schema attribute hibernate uses this specified schema, otherwise it is used user default schema that you can provide via hibernate.default_schema.
Also you can try to write your custom schema name resolver. As it stated in the documentation for the hibernate.schema_name_resolver property:
By default, Hibernate uses the org.hibernate.dialect.Dialect#getSchemaNameResolver. You can customize how the schema name is resolved by providing a custom implementation of the SchemaNameResolver interface.

Spring. load application.properties with sections

I ask you for help.
I have a file with properties:
[dbname1]
host= ...
port= ...
username= ...
password= ...
[dbname2]
…
[dbname3]
…
[.......]
There are more than 1 number of sections.
Name of DB may be any.
Can you tell me please what is better way to read properties from file with sections: to realize it with PropertySourcesPlaceholderConfigurer or any other standart way of Spring Boot?
Thank you!
You can't have sections in a properties file
https://docs.oracle.com/cd/E23095_01/Platform.93/ATGProgGuide/html/s0204propertiesfileformat01.html
You can use YAMLformat instead ( it's supported by spring boot )
https://www.baeldung.com/spring-yaml
YAML Format supports hierarchical properties definition and you can have override them per Profile in the same file

How to use Hibernate with multiple databases on a single server

Our application allows our customer to have multiple databases, all running on one instance of the database server.
For example, databases might be dbcommon, dbLive, dbStaging, dbUAT, dbDev, dbSandbox. The common database and the Production database always exists, but the others are optional (and there is no limit). In dbcommon there is a table that tells us all the databases....so that's where I would need to start. The tables in common are different from the others, and the others all have the same schema (subscriber data)
Using Hibernate, how can I dynamically create/use a connection to either Live or Staging (or any of the others)? I am using Spring if that helps.
I have come across answers that suggest creating different connections in configuration, but because the number of subscriber databases can vary (per install, not while the app is running), this isn't an option for me.
As I discovered after posting this question, and as the user manish suggested, Hibernate's Multi Tenancy support (using the Database MultiTenancyStrategy) works for me. I had to piece together a solution using various resources (listed below).
http://www.ticnfae.co.uk/blog/2014/07/16/hibernate-multi-tenancy-with-spring/
Setting up a MultiTenantConnectionProvider using Hibernate 4.2 and Spring 3.1.1
Multi-Tenancy with Spring + Hibernate: "SessionFactory configured for multi-tenancy, but no tenant identifier specified"
I'm still looking for a way to be able to reference the common (shared) database at the same time as tenant databases...and will try to add that to this answer when complete.
The simplest way I can see to do this is to manage everything via profiles in Spring.
I accomplished this by using application.yml. I'm also using a Hikari connection pool, but that doesn't effect the configuration too much.
Here is an example of a application.yml with 3 profiles listed, and I've defined two of them as an example.
spring:
profiles:
include: dev,test,production
active: dev
---
spring:
profiles: dev
oms:
omsDataSource:
driverClassName: com.informix.jdbc.IfxDriver
jdbcUrl: jdbc:informix-sqli://devdb:9000/hol:INFORMIXSERVER=m_tcp_1;client_deve=en_US.8859-1;db_deve=en_US.8859-1;LOBCACHE=-1
password: oms
username: oms
connectionTestQuery: select count(*) from systables
maximumPoolSize: 5
---
spring:
profiles: test
oms:
omsDataSource:
driverClassName: com.informix.jdbc.IfxDriver
jdbcUrl: jdbc:informix-sqli://testdb:9000/hol:INFORMIXSERVER=m_tcp_1;client_deve=en_US.8859-1;db_deve=en_US.8859-1;LOBCACHE=-1
password: oms
username: oms
connectionTestQuery: select count(*) from systables
maximumPoolSize: 5
In my DB config class, I set the JPA repositories, and tell it what entityManager to use. I also setup the configuration properties to pull frmo the application.yml . This means it will swap out the details based on the profile the app is using on launch.
#EnableJpaRepositories(entityManagerFactoryRef = "entityManagerFactoryOms",
transactionManagerRef = "transactionManagerOms",
basePackages= "persistence.oms")
#Configuration
#ConfigurationProperties(prefix = "oms.omsDataSource")
public class omsDbConfig extends HikariConfig {
//This will automatically fill in the required fields from the application.yml.
#Bean
public HikariDataSource orcaDataSource() throws SQLException {
return new HikariDataSource(this);
}
//I use that datasource to define my entityMangerFactory
#Bean(name = "entityManagerFactoryOms")
public LocalContainerEntityManagerFactoryBean entityManagerFactoryOrca() throws SQLException {
JpaVendorAdapter adapter = new HibernateJpaVendorAdapter();
Properties props = new Properties();
props.setProperty("hibernate.dialect","org.hibernate.dialect.InformixDialect");
LocalContainerEntityManagerFactoryBean emfb =
new LocalContainerEntityManagerFactoryBean();
emfb.setDataSource(orcaDataSource());
emfb.setPackagesToScan("persistence.oms");
emfb.setJpaProperties(props);
emfb.setJpaVendorAdapter(adapter);
return emfb;
}
}
The entities and repositories are defined normally, there's nothing special there. The DB will switch connection based on whatever profile I tell it to run.
I just switch out the active profile in the application.yml to whichever one I need.
Safety note: Define a production profile, don't have production as a default profile.

Configuring data source URL in Spring without XML

I have a simple Web MVC application using Spring Boot that communicates with a database; the DB is H2 and has been in memory until now. I want to change that, and thus use a jdbc:h2:file:... URL.
Up until now, I have not needed to add any XML to configure my application, and I'd prefer it to stay that way if possible. But I can't figure out how to specify a different JDBC URL. I obtained and inspected the data source by passing it to an #Bean method:
org.apache.tomcat.jdbc.pool.DataSource#745e6f01{ConnectionPool[
defaultAutoCommit=null;
defaultReadOnly=null;
defaultTransactionIsolation=-1;
defaultCatalog=null;
driverClassName=org.h2.Driver;
maxActive=100;
maxIdle=100;
minIdle=10;
initialSize=10;
maxWait=30000;
testOnBorrow=false;
testOnReturn=false;
timeBetweenEvictionRunsMillis=5000;
numTestsPerEvictionRun=0;
minEvictableIdleTimeMillis=60000;
testWhileIdle=false;
testOnConnect=false;
password=********;
url=jdbc:h2:mem:testdb;DB_CLOSE_DELAY=-1;DB_CLOSE_ON_EXIT=FALSE;
username=sa;
validationQuery=null;
validationQueryTimeout=-1;
validatorClassName=null;
validationInterval=30000;
accessToUnderlyingConnectionAllowed=true;
removeAbandoned=false;
removeAbandonedTimeout=60;
logAbandoned=false;
connectionProperties=null;
initSQL=null;
jdbcInterceptors=null;
jmxEnabled=true;
fairQueue=true;
useEquals=true;
abandonWhenPercentageFull=0;
maxAge=0;
useLock=false;
dataSource=null;
dataSourceJNDI=null;
suspectTimeout=0;
alternateUsernameAllowed=false;
commitOnReturn=false;
rollbackOnReturn=false;
useDisposableConnectionFacade=true;
logValidationErrors=false;
propagateInterruptState=false;
ignoreExceptionOnPreLoad=false;
}
(newlines mine)
The setup of that bean seems rather intricate, so I want to interfere with it as little as possible - just replace the default JDBC URL.
How can I configure individual properties for Spring to create the datasource? Preferably in Java, but if there is a concise XML way I'm happy as well. I just want to avoid adding 100 lines of boilerplate for something equivalent to url=...
A DataSource is auto configured by Spring Boot for you. To influence how and what there are several properties you can set. Those are prefixed with spring.datasource, for a list take a look at the Spring Boot Reference Guide for a full list.
In your case simply add the following to the application.properties file
spring.datasource.url=jdbc:h2:file:...
This will tell Spring Boot to use this URL instead of the default.
As H2 is considered an in-memory database and not a regular database, when using JPA this will lead to your database to be dropped when the application is stopped. To fix this simply add the following
spring.jpa.hibernate.ddl-auto=update
To specify a dialect simply add the following
spring.jpa.database-platform=org.hibernate.dialect.H2Dialect
or even simpler
spring.jpa.database=H2

Categories