Getting SQL script from Hibernate update - java

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)

Related

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 any lightweight JDBC wrapper with these features?

Named parameters, just like JdbcTemplate from Spring
XML configuration for JDBC connection settings
XML configuration for queries. Something like Hibernate <sql-query>. See Named SQL queries for an example
I'm thinking of trying to build my own, but I thought I'd ask here, maybe it's already been done.
Obviously I don't want to use neither an ORM nor JdbcTemplate.
What about MyBatis?
(source: mybatis.org)
I'am looking for the same thing, meanwhile try out DBUtils Utility:
http://commons.apache.org/dbutils/
Lightweight, open source and no dependencies.
Try JdbcSession from jcabi-jdbc. It's simple (as you want) and requires you to create a java.sql.DataSource before, for example (using BoneCP and H2 database):
BoneCPDataSource source = new BoneCPDataSource();
source.setDriverClass("org.h2.Driver");
source.setJdbcUrl("jdbc:h2:mem:x");
String name = new JdbcSession(source)
.sql("SELECT name FROM user WHERE id = ?")
.set(555)
.select(new SingleHandler<String>(String.class));

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.

Generated queries contain schema and catalog name

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.

Hibernate: hibernate.hbm2ddl.auto=update show generated sql

I wish to pass to Hibernate's SessionFactory
hibernate.hbm2ddl.auto=update
and see in log file generated sql statements. Is it possible w/o java coding (know how to achieve the result with SchemaExport, but hope that hibernate has "in box" solution)
You could setup logging to System.out using
SessionFactory sf = new Configuration().setProperty("hibernate.show_sql", "true")
or log4j
log4j.logger.org.hibernate.SQL=DEBUG, SQL_APPENDER
log4j.additivity.org.hibernate.SQL=false
EDIT: This maybe also helpful Hibernate sql logging with values
You can also set a debug breakpoint on
org.hibernate.tool.hbm2ddl.SchemaUpdate.execute(boolean, boolean)
and see how it goes.

Categories