Generated queries contain schema and catalog name - java

I've the same problem as described here
In the generated SQL Informix expects catalog:schema.table but what's actually generated is
catalog.schema.table
which leads to a syntax error.
Setting:
hibernate.default_catalog=
hibernate.default_schema=
had no effect.
I even removed schema and catalog from the table annotation, this caused a different issues : the query looked like that ..table same for setting catalog and schema to an empty string.
Versions
seam 2.1.2
Hibernate Annotations 3.3.1.GA.CP01
Hibernate 3.2.4.sp1.cp08
Hibernate EntityManager 3.3.2.GAhibernate
Jboss 4.3 (similar to 4.2.3)

Note that there is a new (as of 2010-04-26) web page, http://www.iiug.org/opensource, that has information about using Informix software with various open source packages, including Hibernate. In particular, there is downloadable code that improves the interaction of Hibernate and Informix.

I ended up with the one of the worst hacks I evever did:
The colon is the offending char wich should be '.' catalog:schema.table.
Informix allows comments in SQL statements select {comment} * from sometable
So I set
hibernate.default_catalog={
hibernate.default_schema=}schemaname
the resulting code looks like
select * from {.}schemaname.tablename
which is accepted by informix query parser.

Delete the schema and catalog attributes from *.hbm.xml.

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 tell Hibernate annotation #Column to be case-sensitive?

I'm trying to do a simple SELECT query in a table named ECM (in uppercase) on a Sybase db with Hibernate. I've annotated my DBO this way :
#Entity
#Table(name="ECM")
public class RelationshipDbo {
...
}
However, I'm facing a "table not found" error : the generated SQL has the table name in lowercase. I cannot change the database configuration to tell it to be case-insensitive.
I've also tried putting quotes like this :
#Table(name="`ECM`")
and this :
#Table(name="'ECM'")
Result : the quotes are added in the query, but the table name is still converted from uppercase to lowercase.
Technical information :
Hibernate 4.3
JPA 1.2
org.hibernate.dialect.SybaseDialect
Have you guys any idea?
EDIT: Also tried this Hibernate changes #Table(name) to lowercase
Then my columns names and table name are automatically quoted, but the names still get lowercased.
I think I have your answer:
Basically, you need to change the naming strategy for you JPA provider. How you do this will depend on how you setup your project.
In my case, using spring boot data I set a property in my application.properties to
spring.jpa.hibernate.naming-strategy=org.hibernate.cfg.EJB3NamingStrategy
Without more details from you I can't give more specifics on how to do this.
My goal is a little different since was trying to create tables upper case and hibernate created them in lower case. Also i was using MySQL not Sybase.
But for me quoting the names like this worked:
#Entity
#Table(name="\"ECM\"")
public class RelationshipDbo {
...
}
Then tables were created upper case. Maybe that helps also for the queries.
What is your Sybase db version ?
SybaseDialect has been deprecated in Hibernate 3.5 and then refactored since Hibernate 4.1 with a bunch of subclasses matching different versions of Sybase. Have you tried one of the subclasses to see if it makes any difference?
org.hibernate.dialect.Sybase11Dialect
org.hibernate.dialect.SybaseAnywhereDialect
org.hibernate.dialect.SybaseASE15Dialect
Try this:
Use backticks as in #Table(name="`ECM`")?
This must work from Hibernate point. If not then problem should be in DB (if i'm not wrong)

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;

Getting SQL script from Hibernate update

I'm looking for way to get the SQL update script when Hibernate automatically updates tables.
I'm using hibernate.hbm2ddl.auto=update in development environment only, and I need SQL script that updates tables for production.
I want these SQL scripts in txt format for revision and potential edit.
How can this be done?
Thanks for any advice.
There are some suggestions and general discussion here.
In a nutshell, you can turn on logging (to standard output):
hibernate.show_sql=true
Alternatively, if you use log4j, you can add this to your log4j.properties file:
log4j.logger.org.hibernate.SQL=DEBUG
Both of these approaches are going to output Hibernate's prepared statements with parameters (so the parameter values themselves are not inline). To get around this, you could use an interceptor like P6Spy. Details on that can be found here.
org.hibernate.cfg.Configuration class has method:
public java.lang.String[] generateSchemaUpdateScript( Dialect, DatabaseMetadata)
what generates the reqiured update script.
I've just implemented this in grails:
configuration = new DefaultGrailsDomainConfiguration(
grailsApplication: grailsApplication,
properties: props)
//this extends hibernate config
Connection c = SessionFactoryUtils.getDataSource(sessionFactory).getConnection(props.'hibernate.connection.username', props.'hibernate.connection.password')
<br/>md = new DatabaseMetadata(c, DialectFactory.buildDialect(props.'hibernate.dialect'))
configuration.generateSchemaUpdateScript(DialectFactory.buildDialect(props.'hibernate.dialect'), md)
)
check SchemaExport script in grails, for further information, it uses hibernate to generate schema.
(I had to implent is as a service because we have external domain model)

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