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

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

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.

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;

Is there a difference between running DBUnit as a USER or OWNER of a schema

Currently I'm using DBUnit for testing my webservices.
When I specify the db user credentials with the OWNER of the schema everything works just fine.
If I change the db credentials to login as a USER I get:
> [Main Thread] ERROR org.dbunit.database.DatabaseDataSet - Table
> 'ens_mrm_configuration' not found in
> tableMap=org.dbunit.dataset.OrderedTableNameMap[_tableNames=[],
> _tableMap={}, _caseSensitiveTableNames=false]
I'm aware the the OWNER should first grant SELECT, UPDATE and INSERT for all tables I want to access (so I did just that) I also created SYNONYMS to refer to the actual tables. In the end both scenario's work, but the first test fails with this ERROR If I run the tests as a USER.
So is there a difference how DBUnit handles this? Im currently working with dbunit 2.4.8 and SpringJUnit.
UPDATE
So I found out that I made a mistake my bad. The tests actually don't
work at all when I test with the USER credentials.
Exactly how are you creating the synonyms?
In Oracle, a synonym can be either public (in which case it is visible to all users) or private (in which case it is visible only to the owner of the synonym). Are you creating public synonyms? Or are you creating private synonyms?
Public synonyms are created using the PUBLIC keyword
CREATE PUBLIC SYNONYM ens_mrm_configuration
FOR schema_owner.ens_mrm_configuration
while private synonyms are not
CREATE SYNONYM ens_mrm_configuration
FOR schema_owner.ens_mrm_configuration
If you are creating private synonyms, the synonyms need to be created in the USER schema.
If you log in as USER, can you run this query and post the results
SELECT owner, object_name, object_type
FROM all_objects
WHERE object_name = 'ENS_MRM_CONFIGURATION';

Spring/Hibernate testing: Inserting test data after DDL creation

I have a Spring/Hibernate webapp that has some integration tests that run on an in-memory HSQL database. Hibernate takes this blank database and creates all of my test tables and constraints thanks to hbm2ddl=create. However, I have a new bean that checks for a particular config value from the database during its afterPropertiesSet() method, and so when this bean is initialized, such a row needs to exist in the database.
Is there any good way to set up a Java/Spring/Hibernate equivalent of Rail's test fixtures? I'm trying to find a way to tell Hibernate "whenever you create this table, insert these rows immediately afterwards". I couldn't find a callback or a hook I could add, but maybe there's another way.
I'm trying to find a way to tell Hibernate "whenever you create this table, insert these rows immediately afterwards"
Since Hibernate 3.1, you can include a file called import.sql in the runtime classpath of Hibernate and at the time of schema export, Hibernate will execute the SQL statements contained in that file after the schema has been exported.
This feature has been announced in the Rotterdam JBug and Hibernate's import.sql blog post:
import.sql: easily import data in your unit tests
Hibernate has a neat little feature
that is heavily under-documented and
unknown. You can execute an SQL script
during the SessionFactory creation
right after the database schema
generation to import data in a fresh
database. You just need to add a file
named import.sql in your classpath
root and set either create or
create-drop as your
hibernate.hbm2ddl.auto property.
I use it for Hibernate Search in
Action now that I have started the
query chapter. It initializes my
database with a fresh set of data for
my unit tests. JBoss Seam also uses it
a lot in the various examples.
import.sql is a very simple feature
but is quite useful at time. Remember
that the SQL might be dependent on
your database (ah portability!).
#import.sql file
delete from PRODUCTS
insert into PRODUCTS (PROD_ID, ASIN, TITLE, PRICE, IMAGE_URL, DESCRIPTION) values ('1', '630522577X', 'My Fair Lady', 19.98, '630522577X.jpg', 'My Fair blah blah...');
insert into PRODUCTS (PROD_ID, ASIN, TITLE, PRICE, IMAGE_URL, DESCRIPTION) values ('2', 'B00003CXCD', 'Roman Holiday ', 12.98, 'B00003CXCD.jpg', 'We could argue that blah blah');
For more information about this
feature, check Eyal's blog, he
wrote a nice little entry about it.
Remember if you want to add additional
database objects (indexes, tables and
so on), you can also use the auxiliary
database objects feature.
It is still not really documented.
In hibernate 3.6 the configuration that allows to run arbitrary sql commands is:
hibernate.hbm2ddl.import_files
See in http://docs.jboss.org/hibernate/core/3.6/reference/en-US/html_single/, noticing there is an error in the documentation: the property is import_files, with an s in the end.
If you're talking about JUnit tests and using AbstractTransactionalDataSourceSpringContextTests there's methods you can override like onSetupBeforeTransaction that provide a hook to pre-populate test table data etc.

Categories