How to connect to specific Schema in H2 - java

So I have created a few schema in H2.
How can I connect to a specific schema in H2
For example when I need to connect to a specific schema in SQL Server I have below JDBC URL
jdbc:sqlserver://HOSTNAME:PORT;SelectMethod=cursor;instanceName=MYSCHEMA;databaseName=DBNAME
Is this feature available in H2.
If not is there a workaround.
I do not want to always access a particular table in my schema instance be accessed like MYSCHEMA.TABLE_NAME
Otherwise I suppose only way out will be to create all table into the default schema that is public

There is such feature supported. See this:
http://www.h2database.com/html/grammar.html#set_schema
You can specify the schema in the connection string:
jdbc:h2:test;SCHEMA=SCHEMA_NAME
You can also change the current schema with:
SET SCHEMA SCHEMA_NAME;
Hope this helps.

SET SCHEMA_SEARCH_PATH shemaName
http://h2database.com/html/grammar.html?highlight=drop%2Calias&search=drop%20alias#set_schema_search_path

You can also supply a schema property in the info parameter of
java.​sql.​DriverManager.getConnection(String url, Properties info).

Related

spring.datasource.url how to create multiple enum/domain before hibernate is scanning the entities

I have spring boot application with pgsql as db. I am writing test cases for the api's and for the test cases i am using h2 db. I have multiple entities where i have multiple enums. For the test cases we have
spring.jpa.hibernate.ddl-auto = create-drop
When hibernate is creating the tables from entity it is giving Unknown data type: "enum_type1".
I took a reference from this question:
How to fake ENUM columns in the H2 database for play unit testing?
So i updated my property as follows:
spring.datasource.url= jdbc:h2:mem:test;MODE=PostgreSQL;INIT=CREATE DOMAIN IF NOT EXISTS enum_type1 as VARCHAR(255),CREATE DOMAIN IF NOT EXISTS enum_type2 as VARCHAR(255);DB_CLOSE_ON_EXIT=FALSE
But it is giving following error:
org.h2.jdbc.JdbcSQLSyntaxErrorException: Syntax error in SQL statement "CREATE DOMAIN IF NOT EXISTS enum_type1 AS VARCHAR(255),[*]CREATE DOMAIN IF NOT EXISTS enum_type2 AS VARCHAR(255)"; SQL statement:
So how can we create multiple enum/domain before hibernate is scanning the entities?
Any help will be appreciated, Thanks.
You can't use a comma as a separator between statements. If you want to specify multiple statements in INIT parameter, they should be separated with \;. Note that INIT=something parameter should be separated from other parameters, such as DB_CLOSE_ON_EXIT with ; (without the \).
jdbc:h2:mem:test;MODE=PostgreSQL;INIT=CREATE DOMAIN IF NOT EXISTS enum_type1 as VARCHAR(255)\;CREATE DOMAIN IF NOT EXISTS enum_type2 as VARCHAR(255);DB_CLOSE_ON_EXIT=FALSE
H2 also has a built-in ENUM data type, it should be better to use it instead of VARCHAR.
PostgreSQL compatibility mode should be normally used with DATABASE_TO_LOWER=TRUE.
And the whole idea to use different DBMS for tests and production doesn't look good. Normally you should use multiple DBMS only when your application is initially designed to work with them all.

how to create database schema with hibernate.cfg.xml

using
< property name="hbm2ddl.auto"> create< / property >
only creates the tables, and whenever a schema does not exist, hibernate fails to create the table because the schema does not exist.
Hibernate will not create the schema for you, but maybe you can tell your DBMS to run some script before hibernate starts to create the schema objects. I found something here and I think you can use it as a start point.

Setting default schema name in Java

I am executing the below query from my Java code:
SELECT * FROM JSTORE.EMPLOYEE
Where 'JSTORE' is the Schema name and 'EMPLOYEE' is the table.
Can I set the schema name to be used as JSTORE so that I needn't specify it in my queries always? I am using Oracle databse.
If that schema name is the same as the user name your application is using to connect to the database, then you don't need to specify the schema name (through Java or SQL*Lite).
If the schema name varies through the application, then I would probably have the schema name present in the SQL to avoid mistakes. Just think about what can go wrong if you ALTER SESSION in a connection pool. It can still be configurable and the process can be automated using some Java code to generate the SQL for you (which you probably should have anyway).
You can execute this SQL:
ALTER SESSION SET CURRENT_SCHEMA=JSTORE
Note that you need to execute this for each now connection that you make (one Oracle session == one Java Connection object).
Be careful when you use pooled connections; if they need different schemas, you need to restore the default before returning them to the pool.

Unit testing Hibernate with multiple database catalogs

I have an issue testing a Hibernate application which queries multiple catalogs/schemas.
The production database is Sybase and in addition to entities mapped to the default catalog/schema there are two entities mapped as below. There are therefore three catalogs in total.
#Table(catalog = "corp_ref_db", schema = "dbo", name = "WORKFORCE_V2")
public class EmployeeRecord implements Serializable {
}
#Table(catalog = "reference", schema = "dbo", name="cntry")
public class Country implements Serializable {
}
This all works in the application without any issues. However when unit testing my usual strategy is to use HSQL with hibernate's ddl flag set to auto and have dbunit populate the tables.
This all works fine when the tables are all in the same schema.
However, since adding these additional tables, testing is broken as the DDL will not run as HSQL only supports one catalog.
create table corp_ref_db.dbo.WORKFORCE_V2
user lacks privilege or object not found: CORP_REF_DB
If there were only two catalogs then I think it would maybe be possible to get round this by changing the default catalog and schema in the HSQL database to that one explicitly defined:
Is there any other in-memory database for which this might work or is there any strategy for getting the tests to run in HSQL.
I had thought of providing an orm.xml file which specified the default catalog and schema (overiding any annotations and having all the defined tables created in the default catalog/schema) however these overrides do not seem to be observed when the DDL is executed i.e. I get the same error as above.
Essentially, then I would like to run my existing tests and either somehow have the tables created as they are defined in the mappings or somehow override the catalog/schema definitions at the entity level.
I cannot think of any way to achieve either outcome. Any ideas?
I believe H2 supports catalogs. I haven't used them in it myself, but there's a CATALOGS table in the Information Schema.
I managed to achieve something like 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;

How to support support SqlServer's ".." in HyperSQL?

tl;dr: I am trying to unit test some SqlServer queries which state the db name but they do not seem to work in HyperSql.
We are using Sql Server in production and I am trying to use HyperSQL as my database for unit testing. I am trying to test a class that creates SQL queries so stubbing out the database is not an option as having the queries parsed by a real database is part of the test.
Queries are supposed to be created in the form of SELECT * FROM EntAsdfDb007..Data_Table, although we can use the schema name ( 'db' ) if we wish.
From what I understand about the SELECT format for SqlServer, it allows you to specify the name of database followed by the name of schema. Also, you can drop the name of the database and have it inferred.
In HyperSqlDb I have been able to create the schema 'db' and create the necessary tables within it, and have been able to create tables within that schema but I have not be able to query with the database name even after setting the DB name using .setDatabaseName(). The exception I get is:
Caused by: org.hsqldb.HsqlException: user lacks privilege or object not found: ENTASDFDB007
Just to be clear: I am unit-testing a class that uses SQL like SELECT * FROM EntAsdfDb007..Data_Table. I am trying to set up an instance of HyperSql for unit testing purposes but HyperSql seems to reject the syntax used.
That won't be possible.
HyperSQL cannot be changed to accept non-standard naming schemes.
It is possible. HSQLDB does have one catalog per database. The catalog name is PUBLIC by default, which you can change.
ALTER CATALOG PUBLIC RENAME TO EntAsdfDb007
You can then access your table with
SELECT * FROM EntAsdfDb007.db.Data_Table

Categories