views:

224

answers:

2

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.

A: 

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.

Brabster
+5  A: 

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.

Pascal Thivent
That's awesome! I can't find much documentation about it, but it works as advertised. Thanks!
CaptainAwesomePants
@CaptainAwesomePants: You're welcome. It's actually an undocumented feature. I'll add the "announcement".
Pascal Thivent
@Pascal Thivent Hi Pascal, I am aware. See what Emmanuel Bernard says here: http://stackoverflow.com/questions/2108178/id-generatedvalue-but-set-own-id-value and let me know what you think
Arthur Ronald F D Garcia
@ArthurRonaldFDGarcia: Hello Arthur. I had a hard time trying to understand Emmanuel's answer, but I think I got it now. Emmanuel is actually answering a comment from the OP left on [another answer](http://stackoverflow.com/questions/2108178/id-generatedvalue-but-set-own-id-value/2109847#2109847) saying *"on startup I want to set a 'no User' with id 0"*. To achieve this, the OP can indeed use the `import.sql`. But this is very different from the original question which is much more generic. Emmanuel's answer doesn't cover the original generic question, only the actual specific requirement.
Pascal Thivent
@Pascal Thivent Very strange!
Arthur Ronald F D Garcia
@Pascal Thivent Hi, can you provide The answer where you highlights a four-series articles about JSR 303 - bean validation ???
Arthur Ronald F D Garcia
@Arthur Do you mean this one: [How do I check that an entity is unreferenced in JPA?](http://stackoverflow.com/questions/3013986/how-do-i-check-that-an-entity-is-unreferenced-in-jpa/3015257#3015257)?
Pascal Thivent
@Pascal Thivent Yes, Thank you (+1)
Arthur Ronald F D Garcia