Spring Datasource and Database Schema - spring

I am trying to declare a Spring datasource pointing to a DB2 database. Presently I am using a org.springframework.jdbc.datasource.DriverManagerDataSource to setup the connection but am not finding any way to specify the database schema in the database in the datasource bean. Could anyone help me on this?

Problem is there is no standard way to set the schema, each database has a different mechanism.
A work around is to set the schema as part of the db url...
For db2 the url will look something like:
jdbc:db2://SERVER_NAME:PORT/DATABASE:currentSchema=SCHEMA_NAME;
hope that helps...
Special note: make sure you add the semicolon ; at the end of the URL, otherwise you will get errors saying URL is invalid. Also make sure nothing after last ; exists (not even spaces).

There isn't a means to do this with the standard Spring namespace. Rob Harrop's response to a request to add the schema to the configuration:
In general, this kind of functionality should be pushed into the connection pool since there is no really elegant and performant way to do this via a decorator. The pool can set the schema once per connection it creates, whereas here you have to set it each time a connection is retrieved.
If you're desperate to set the proxy in your configuration, the submitter included some code for a proxy to allow the schema to be specified.

If your connection uses the owner of the schema as the user then that connection will point to that particular schema.
ie. If user user1 is the owner of the database schema named schema1 then if you connect to the database using user user1 then by default the connection will point to schema1.
We have used UserCredentialsDataSourceAdapter provided by spring to connect to different schemas based on the logged in user. This provides a datasource which is pointing to a particular schema based on the user. This uses a thread based login information. Each thread has to decide to which schema it has to connect and provide the user according to that.

Related

How check the whether database user mentioned in property file has granted access to all table defined in schema on startup of restful service

Rest service: Spring rest
DB: Postgres
Problem definition: In production env, we are getting issues due to lack of permission on the table for the user configured in the property file.
All such issues generally got notified at runtime only.
To Avoid such permission related issues, Is there any out of box way in spring boot which will check whether the user-defined in property file has all the select/delete/insert/update permission on all tables that are created in the schema.
I do understand we can use hibernate.hbm2ddl.auto=validate but this only checks datatype, missing table, missing column issues only.
Thank you.
Regards,
Kiran.
I think there is no way to handle the situation from spring boot. Finally I reached to conclusion that i can handle it in Database and would grant permission to the table and sequence created in future too.
Kindly see below URL,
https://aws.amazon.com/blogs/database/managing-postgresql-users-and-roles/
Thank you.

How to use Multitenant in Nhibernate with Spring in MVC

I have an application in MVC with Hnibernate deployed on a server. Currently only one client is using this application. Now there are many clients and all will use this app with different database but the schema will same for all.
For this implementation I am thinking an approach-
I have made a new database in which table hold the information regarding the individual Client database connection strings.
When the application run, Nhiberate makes multiple session factories for all database which includes all client databases and the main database.
For example- there are two clients 'A' and 'B' with their database name 'A_db' and 'B_db'. And the other main database which hold connection strings as 'All_db'. Then in this case nhibernate make 3 session factories for all three db.
So when user enter their login credential, i'll check the related connection string for that client from the main database. and then destroy all session factories which are not related to that client database connection string. So by doing this there will be only one session factory remain that belong to his database.
Is this my approach is correct??
And i am going in right direction then provide some code for this approach as making multiple session factories and after then removing all session factories except the related one?
You can supply a connectionstring to the GetSession method. Check out this link for more intel.

Passing ClientInfo/ClientIdentifier on syscontext/connection with Hibernate for audit purposes

I have a web service which processes inserts/updated data to DB. When client calls this webservice, UserId(currently logged in user to portal) will be sent in Request. I need to pass this userId to Db connection or set it in sys context for Audit purpose. we have existing audit tables and triggers to inserts/updates to Audit table after insert/update on actual table. So to track these changes I need to pass this UserId somehow to connection so that it can be retrieved from DB from Sys Context or $session and inserts in Audit table. I am currently using Spring and Hibernate transactions to process data with DB.
I tried to Set client info on Connection but it's not working. I tried below:
Session session=sessionFactory.getCurrentSession();
SessionImpl sImpl=(SessionImpl) session;
Connection connection=sImpl.connection();
connection.setClientInfo("ClientUser", "ABC");
And also I am trying to set client info by calling Stored procedure DBMS_APPLICATION_INFO.SET_CLIENT_INFO before performing operation on DB every time from application code.but I am not sue if it's a correct way to handle it.
I am trying it with both OCI and thin JDBC drivers but not able find a way to set this user id.
Can someone let me know if there is any efficient way to pass user id on sys context or with Connection. I am currently using hibernate4, Spring, Websphere Server, Oracle DB.
I am using Spring #Transactional to handle hibernate Connections and transactions to perform operation on DB.Connections are from Connection pool and I am using org.springframework.jndi.JndiObjectFactoryBean for dataSource.
is there any way to have interceptor or wrapper around connection to set it when we get the connection from connection pool.
Has anyone done this before?
This is described in spring data JDBC Extensions for the Oracle Database
Chapter
8.2 Configuration of a Custom DataSource Connection Preparer
...but you could implement a ConnectionPreparer that would use the current users login id. That way you can capture user login information even if your data source is configured with a shared user name.
This is a solution for oracle, which I think you are using. It should be also possible to adapt that to another database.

Hive JDBC fails to connect configured schema

I am able to connect to Hive using hive-jdbc client and also using the beeline.Typical url is,
jdbc:hive2://hive_thrift_ip:10000/custom_schema;principal=hive/hive_thrift_ip#COMPANY.COM
Unfortunately the connection is always established to the 'default' schema of Hive , and it is not considering the configured schema name in the url. I use the org.apache.hive.jdbc.HiveDriver class
It always takes me to the tables of the default schema. Still I am able to access the tables from other schema using the schema name prefix to the tables, like custom_schema.test_table
Kindly let me know if I missed any property or configuration in the connection creation part which will help me in getting the session exclusively for the schema that configure in the url.
Many thanks.

Seting Schema for HSQLDB in JDBC connection

How does one set the schema for HSQLDB in the JDBC URL itself.
Kinda how you can do in MySQL with jdbc:mysql://localhost:3306/
-EDIT-
My current DB url looks like this
jdbc:hsqldb:file:C:\\hsqldb\\dbname
Also inside the dbanme there is a schema newSchema, which can be set using
set schema newSchema,
how do i do this using the jdbc URL itself.
have you already tried the standard protocol?
"jdbc:hsqldb:hsql://[HOST]:[PORT]/myDBName"
How are you trying to connect? through a standalone app or by creating a resource?
You might have seen this but still check here if not done:
http://hsqldb.org/doc/2.0/guide/dbproperties-chapt.html#dpc_connection_url
I think need to specify the port number like as shown //192.0.0.10:9500
UPDATE:
I have been doing some more testing. The suggested solution appears to be ineffective.
For example; if I set the schema to Test I still may not use SQL on tables in that schema. Essentially that extra stuff I put in there has no effect, even though I thought it was OK.
select * from BOOKMARKS;
SEVERE SQL Error at '<stdin>' line 5:
"select * from BOOKMARKS"
user lacks privilege or object not found: BOOKMARKS
SquirrelSQL has an option for an initial schema, so queries there work OK. The sqlTool accepts the URI but doesn't change/select the schema. It is slightly frustrating that I can't see HOW to report the current schema name in use btw.
So this answer doesn't solve the problem; I'm leaving it here because it will save the next person time when they find a good answer to the challenge.
back to the drawing board ...
original suggestion ...
I'd like to do this too. For example with mysql the example is:
mysql -h hostname:port schema
The port number, being one port per database. Now in HSQLDB, the URL is one database within a Catalog (that's how they spell it). Here's the solution I came-up with. I have ...
databsee: dev
schemas
public
test
In my RC file, ~/.config/sqltool.rc ...
urlid dev_test
url jdbc:hsqldb:hsql://localhost/dev;set schema test;
username programmer
password secret
I can use the connection ID dev_test to link to the test schema, the normal default is public. And you can run the sql tool with:
java -jar /usr/lib/hsqldb/lib/sqltool.jar --rcFile=~/.config/sqltool.rc dev_tmp
That approach worked with a Groovy Sql connection:
url: 'jdbc:hsqldb:hsql://localhost/dev;set schema test',
...
Worked just how I'd want it. So what I can do is append the schema I want to that URL connection string string. It may no be the solution but it will do what you describe.
Looking at the connection protocol: there is NO option for a schema nor for a catalog. So catalog will be part of your URL, eg. if you use a file base database, that is one catalog.

Resources