Spring with Hibernate- how to pass schema name dynamically - spring

I am using spring-Hibernate DAO Layer, i have created spring configuration file having data source and all the hbm xml list and each hbm is mapped with the table as
table ="schema1.table1"
We have another schema say prodSchema in production, i want to know how to pass schema name dynamically by using propfile etc.to the hbm file so that in runtime i can change.

Java annotation only supports compile time constants. i.e. you cannot put variable in annotation parameter.
REf : http://docs.oracle.com/javase/specs/jls/se7/html/jls-15.html#jls-15.28
Your situation is common to most of the project and developer. I generally use external database configuration file, where I put the connection parameters, schema and credentials. This file is created on each environment once and remains unchanged until there is any change in DB server.
General Hibernate Property for quick reference.
hibernate.connection.driver_class : JDBC driver class
hibernate.connection.url : JDBC URL (may contain schema)
hibernate.connection.username : database user
hibernate.connection.password : database user password
hibernate.default_schema : Qualify unqualified table names with the
given schema/tablespace in generated SQL. e.g. SCHEMA_NAME (use this
if you don't specify in JDBC URL)

Related

Springboot 2.7.2 with Hibernate 5.6 Error ORA 32575 during INSERT

Using Springboot 2.7.2 and Hibernate 5.6 with Oracle 12.2 to write a web application. I use the repository model to do an insert and test with mockmvc. With SQL Debug turned on I get an error ORA 32575 at the point where it executes the insert statement. In the debug log it has INSERT INTO TABLE (COL1, COL2, ID) VALUES ('X','Y',DEFAULT). The Oracle error 32575 follows this. The ID field in question is part of a Hibernate pojo and is a primary key and uses GenerationType.SEQUENCE. It is an Entity that points to a Table.
The DataSource is "thin" driver using the ojdbc8.jar. The Datasource is set up using a #Configuration" annotation in the application during Tomcat startup. If you take all of this by itself I dont get the error above.
However, I have a requirement to connect to each database user through a PROXY USER account because we use Oracle Label Security. It looks something like GRANT CONNECT TO userX THROUGH proxyuser. Using the database driver it would be something like
Properties proxyProps = new Properties()
proxyProps.set(Connection.PROXY_USER_NAME, user)
oraCon.openProxySession(Connection.PROXYTYPE_USER_NAME)
This is being done inside of an application class called ProxyDelegatingDatasourceThin which extends DelegatingDataSource which is a Spring class that I believe gets called when a new connection attempt is made.
Again, queries work fine, updates seem to work, its only the INSERTS. The ID column itself is set to NUMBER and is flagged as a Primary Key. It is not set as any kind of an IDENTITY column.
The error seems to want the ID column to be omitted from the INSERT Statement all together but Hibernate or Spring is generating it with the DEFAULT in the VALUES that is associated to ID.
Im hoping someone can help. Spent days on this.
Set the #ID column to be nullable, insertable, updatable all set to false
Tried using merge and persist from the entity manager (EntityManager) instead of using the Spring Repository save() method.
The implicit caching property is set to true
The error seems to want the ID column to be omitted from the INSERT Statement all together but Hibernate or Spring is generating it with the DEFAULT in the VALUES that is associated to ID.
Adding more info...
When I remove the code above which opens the proxy session, I don't get the error. I also printed some info from the database context while using the proxy session and the PROXY USER is to the PROXY ACCOUNT and the SESSION user is to the user that is connecting through the PROXY ACCOUNT.
Whether I use the Oracle Thin Driver or UCP I get the same result.

Why I can't find my tables in H2 schema / How can I validate which H2 schema my Spring boot app is working with?

I'm running a spring boot app
didn't have any setting for h2 other than maven
when i'm connecting to the h2 console i can see the tables that were supposed to be created for two entities
i connected with the JDBC URL: jdbc:h2:mem:testdb (which is supposed to be the default)
Is there a way to make sure what schemas is H2 currently running/ or some log file for H2 ?
in my application.properties i have this:
spring.h2.console.enabled=true
spring.h2.console.path=/h2
I read somewhere that H2 initializing itself upon login, but a demo i was watching these were the exact steps taken , so not sure that is the case.
these are the settings in the H# console:
You can explicitly instruct spring boot to create and connect to a particular schema in H2 with config as below.
spring.datasource.url=jdbc:h2:~/test;DB_CLOSE_DELAY=-1;DB_CLOSE_ON_EXIT=FALSE
spring.datasource.driverClassName=org.h2.Driver
spring.datasource.username=sa
spring.datasource.password=sa
This creates a datasource of name test database in h2 in file mode. There would be a file called test.db in your home folder which would be the data file for the database.
DB_CLOSE_ON_EXIT property decides to recreate the database on every restart.
There is an easier way to tell Spring JPA the default schema for your H2 data source by just adding the "SET SCHEMA {default schema}" in the datasource url, e.g.:
spring.datasource.url=jdbc:h2:mem:testdb;DB_CLOSE_DELAY=-1;INIT=CREATE SCHEMA IF NOT EXISTS testdb\\;SET SCHEMA testdb
I actually saw the right schema all along
The reason I thought I wasn't seeing the right schema was - the JPA Entities I expected to see, were not there.
I then found that this was because I didn't name the package for the JPA entities correctly
I named it "domain" (see pic):
I should have named it com.example.domain as can be seen:
This is because Spring Boot looks is doing a #ComponentScan "under" the package with the main class , so I had to prefix the "domains" with the name of the package that the main class resides in, which is com.example.
For me I had to check the log when I run Sprinboot
jdbc:h2:mem:9967b201-6b59-4925-acb3-d2e50dc5d9a5. --> this can be any other auto generated UUD
Adding this to your JDPC URL in the browser will let you see the tables that you created.

Loading dynamic externalized property files

This is a spring 2.5 based project. I need to load a externalized property file when
application server starts up.I am shipping my solution to 10 users.(10 Jboss instances) where
each connect to their own database schema. Each user has a client id value saved in the
database. This will be the name of the externalized property file. If the property file name is fixed I could
load as below
<context:property-placeholder
location="classpath:/tmp/client001.properties" />
please help to find a approach how to load this when name of the property file (client001) is in the
database.
Loading dynamic externalized property files
You could take the name of the file from a system variable, loaded with the corresponding value on each server.
Take a look at this question.
Spring: Injecting different properties file according to profile

How can I change the value for application.properties dynamically?

How can I change the value for application-properties.xml file dynamically through the program in the spring hibernate framework. Actually Iam using config-mysql.xml for connecting database. In that I want to change the database name dynamically at runtime. for example in that file having jdbc:mysql://localhost:3306/usermgmt . now I want to change the usermgmt value at dynamically.Thanks in advance.

Jdbc Connection Pooling - using multiple schema known at runtime only

I am working on an engine that is doing the following:
gets data provider info from DB (that tells me to what database & schema details to connect to get my data)
use that info to connect to the database and get my data, that later I use to build some XML content.
The standard setup to handle and isolate database connection management would be to create a DataSource bean (I'm using Spring to wire my components) and inject that in my ProviderConfigDao (loads connection config) and ContentDao (loads data using connection details loaded previously). This would nicely isolate the handling of the connections from the actual code, thus the DAO classes not needing to know how and when a connection is created/opened/closed etc.
This setup doesn't work unfortunately, as when I create my connection, I need to be able to specify the database schema. I don't know all the different schemas from the beginning, so I can't create a set of DataSource objects to cover all of them, thus the DataSource object must be created at runtime and it's creation hidden from the users.
The only solution I can think of is:
Have another class/interface (DataSourceProvider) having one method:
//Gets the connection URL as parameter (which includes the schema name).
DataSource getDataSource(String url);
Add a bean in Spring config to provide a custom implementation for it that manages creation of DataSource objects for each schema.
Inject that object to my DAO classes instead of the DataSource object.
It's not a bad solution, but I was wondering if there is maybe support for something like this already in some open source package ... I'd rather use something already done and tested then reinvent the wheel.
Cheers,
Stef.
there's a JDBC Utils to get all the metada from a database org.springframework.jdbc.support.JdbcUtils
parameters:
DataSource
Implementation of org.springframework.jdbc.support.DatabaseMetaDataCallback

Resources