How to select schema at runtime using Hibernate? - java

I already have an existing code base, where schema(like db_1, db_2..) are created at run time.
We are currently using JdbcTemplate, using that its quite easy to append schema in the native SQL queries some thing like :-
sql = " Select * from "+schema+".user";
jdbcTemplate.query(sql, new UserMapper());
Now I want to know is how to provide schema to hibernate at runtime like I did with the jdbcTemplate?
What connection url should I provide in hibernate.cfg.xml so that it doesn't connects to a single schema rather whole database?
Any suggestions will be helpfull.
P.S: I am new to hibernate (So I might have missed something stupid)

I know of two options:
Use native SQL query binding results to JPA entities. Details here.
Use Hibernate multi-tenancy. Details here and here.
Although I haven't tried either.

Related

How to write in test case with in-memory-database?

I am using Oracle as my database, Spring Boot as my framework.
I don't know how to write a test case to check database query?
I have heard that it is possible through In-Memory Database. But don't find a proper example.
Suppose in my code I have written a SQL query that SELECT * FROM tableName and it is returning me a ResultSet Object.
So in while writing test case how can I check that?
Every time I don't want to go into the database and fetch a query.
I know that is possible but my question is how can I replace my query's result with a dummy result which I will store in any file.
Thanks in advance
You should initialize your Hibernate SessionFactory with another hibernate config, that uses H2 in-memory database, example test-hibenate.properties:
hibernate.dialect=org.hibernate.dialect.H2Dialect
hibernate.connection.url=jdbc:h2:mem:orm
javax.persistence.schema-generation.database.action=drop-and-create
Then in your tests you can use your DAO's just in regular way.
If you use plain JDBC, you can create connection to H2 in-memory database this way:
Connection connection = DriverManager.getConnection("jdbc:h2:mem:test;DB_CLOSE_DELAY=-1", "", "");
And you will need H2 database dependency:
https://mvnrepository.com/artifact/com.h2database/h2

Embedded database and multiple catalogs

I want to create integration tests for my repositories. The production database is Sybase and it consists of multiple catalogs in which there are multiple schemas.
In my code I use multiple queries I am selecting data across different catalogs: ex:
select *
from catalog_a.schema_a.table_1 aa1, catalog_b.schema_a.table_2 ba2
where aa1.c1 = ba2.c2
So for the tests I would like to create embedded database, like H2, HSQLDB or something different. I was trying to find something that would allow me to simulate prod db with multiple catalogs, but I couldn't make it work. Please advice and suggest the solution.
I am writing app in java/spring. Additional trick here is that my app is creating only one DataSource to database.
HSQLDB supports only a single catalog and the name is checked when the catalog is specified in a query. You can change the catalog name from the default PUBLIC to something else. For example:
ALTER CATALOG public RENAME TO to catalog_a
But using two different catalog names is not supported.
If your schema or table names in the two catalogs are different, you could modify the source code of HSQLDB and disable the catalog name check for your tests in the method org.hsqldb.ParserDQL.checkValidCatalogName(String name)
I managed to achieve this in H2 via IGNORE_CATALOGS property and version 1.4.200.
However, the url example from their docs did not seem to work for me, so I added a statement in my schema.xml:
SET IGNORE_CATALOGS = true;

Query with dynamic schema without using string concatenation

I have a system that uses a Oracle database, with a schema that is different from the application user. The schema name itself is not known in advance, so we can't just hardcode it. It's a system property.
Most of the data access is through Hibernate, which can specify the default schema on connection so this is not a problem in those cases.
However, there are a few places where plain SQL queries are used (using spring jdbcTemplate). So right now we have something that boils down to:
Map<String,Object> result = jdbcTemplate.queryForMap("SELECT A, B, C FROM "+schema+".TABLE WHERE blablablah");
And this, of course, is an open SQL injection vulnerability. We're planning security audits and this will be flagged for sure.
So the question is: How do I specify the schema on the query, be it with jdbcTemplate, another Sprint data access utility, or even plain jdbc?
Thank you,
JGN
You can use Connection.setSchema to specify the schema for a JDBC connection. This should be done before you create the Statement to execute a SQL command.

Apache ibatis postgresql selectList how it it works

I have installed postgresql enterprise DB and created some tables
In one of the example. I see the following code.
import org.apache.ibatis.session.SqlSession;
.....
SqlSession session = sessionFactory.openSession();
.....
List list = session.selectList("findAllData-Data", params);
What it does? findAllData-Data means what? I have only created tables in postgresql, but I don't see the table name in above code
Check up the documentation for selectList
"findAllData-Data" is the unique identifier matching the statement to use. Statements are usually defined in some mapper .xml file or in newer versions in annotation of a class, so grep your code for findAllData-Data in order to find the definition.

SQL\HQL queries repository

While working on some java projects i've saw some sort of SQL repository.
The idea was to place all queries in one(or few) xml files and retrieve them when needed by name. Something like this:
String sql = getSQLRepository().getSQL("SELECT_ALL_ROWS", params)
String sql2 = getSQLRepository().getSQL("SELECT_ROWS_WITH_COND", params)
In my current Grails project i have a lot of HQL queries in dozens of classes and it's hard to track them all. It seems that HQL repository would be very nice solution.
So could anyone tell if some sort of SQL\HQL repository implementation allready present or there are better solutions present ?
Have a look at Mapping Queries in Hibernate reference.
After we started use the http://source.mysema.com/display/querydsl there is no need to think about text queries and how to manage them.
I'd recommend you to use the good old properties files. You can put them into your classpath and then use as following:
Properties sql = new Properties();
properties.load(getClass().getResourceAsStream("sql.properties"));
////////
String query = sql.get("SELECT_ALL_ROWS");
I'm sorry, and it doesn't relate to Hibernate, but when I worked with iBatis, - there are the situation as you are writing about exactly. A few xml (partially generated itself) files, containing SQL queries, which was easily to use in DAO

Categories

Resources