What is the fastest way to clear out a database using NHibernate? - nhibernate

I intend to perform some automated integration tests. This requires the db to be put back into a 'clean state'. Is this the fastest/best way to do this?
var cfg = new Configuration();
cfg.Configure();
cfg.AddAssembly("Bla");
new SchemaExport(cfg).Execute(false, true, false);

var se = new SchemaExport(conf);
se.Drop(false, true);
se.Create(false, true);

Yes it almost is. You don't have to create a new configuration object before each test, you can reuse it when created once. You can make it faster by using an inmemory database like sql-lite for testing.

My integration tests do SessionFactory creation in a base class constructor, and SchemaExport in test fixture setup. I also test against SQLite running as an in-memory database for extra speed.
Ayende gave a good example of this approach in this blog post. Tobin Harris' article includes timing data of drop/create vs delete.

Me I use Proteus, it's an open source library. Before each test, there is an auto save of your set of data , load the set you want to test (an empty DB for exemple). After each test, the set of data is reloaded after the last test, the data present in the database before the tests are restored.

Since NHibernate is database independent another interesting option if you are having it generate your database is to run your tests against something like SQLite which is in memory. Things will run MUCH faster that way.
Here is an article on showing how to do this with ActiveRecord but you can take the concept and use it without ActiveRecord.
And here is a discussion if you're having trouble getting it working (I did at first).

Related

Single FakeApp for all test in Play Framework

I want to have single FakeApplication for all my test.
My final goal is to set up database and use it in all test. They should access single database and share data in it. I can not use H2, because I use some MySQL features(fulltest search, for example). But if there is no started application, I can't call "DB.withTransaction" because there is started application yet. But it should start once, because it drops all tables and create new ones.
How can I do it?
I am using scala and JUnit. I solved my problem next way: I just created singleton for my fake application, which is retrieved as an implicit val. So, all work about creating and cleaning database is done on first fetch.

MVC3 NHibernate, SQL audit

I have some misunderstandings about the implementation of an SQL audit module, using as ORM Fluent NHibernate. So here is the situation:
We are talking about a Client-Server application build on MVC3 framework.
Suppose there we have a method which renders the grid:
[HttpGet]
public ActionResult ShowGrid()
{
var gridModel = _gridService.GetAllRecords();
return View(gridModel);
}
Now when somebody executes a DB Inser/Update/Delete command, I want that every client which views that grid to see that there are some changes inside.
I have 3 ideas:
1) To write a script that makes a refresh by calling the database, each X seconds. Making a full Select even if there are no changes yet. Worst decision
2) To create some sort of trigger, which updates a custom audit table, and then to check if there is some new data, by comparing some Object State/ LastUpdate fields. Better
3) To use some other tools (no have ideea what tools), that will offer some solutions.
If somebody have some information, maybe there already exists a solution please share. Thank you very much!
Using NHibernate, the easiest way:
NHibernate Interceptor
If you need implement something more complex you can mix it with event listeners:
Here
Or use:
NHibernate.Envers

programmatically set show_sql without recreating SessionFactory?

In NHibernate, I have show_sql turned on for running unit tests. Each of my unit tests clears the database and refills it, and this results in lots of sql queries that I don't want NHibernate to output.
Is it possible to control show_sql without destroying the SessionFactory? If possible, I'd like to turn it off when running setup for a test, then turn it on again when the body of the test starts to run.
Is this possible?
The only place you can set this is when building a NHibernate.Cfg.Configuration.
Once you've created a SessionFactory from your Configuration, there's no way to access the configuration settings, which I think is one of the reasons for using a factory pattern: to ensure that instances once successfully built can't be messed up by runtime re- or mis-configuration.
If you really need that feature, get the NH source code and find the place where the show_sql setting is evaluated.
Another option although it may/may not be as good is to use NHProf and just initialise NHProf when testing.
NHProf doesn't log setting/clearing database just queries used.

How to use test-data w/o deleting 'old' information?

As described in the playframework documentation, I'd like to import data from the yaml-file in order to perform tests. However, I'd like to keep - or at least roll back after the tests - the existing entries in the database.
Any hints are appreciated.
regards
- alex
The easiest approach is to use the Fixtures.
So, in your unit/functional test, you can do
#Before
public void setup() {
Fixtures.deleteAll();
Fixtures.load("data.yml");
}
This will clear all the data out, and reload the data into the database before the test is executed.
To achieve the same thing for your selenium tests, you just do
#{selenium delete:'all', load:'data.yml'}
You can't easily revert the database back to what is was prior to the unit test, but I would suggest that your test database should be entirely populated by your YAML file anyway, so that you have complete control over the data that your tests are be tested over.
As far as I can estimate, dbUnit, an extension of JUnit, would be an appropriate solution for this problem.

How do I delete all JPA entities?

In my testing code I need to have a blank/empty database at each method. Is there code that would achieve that, to call in the #Before of the test?
Actually you always can use JPQL,
em
.createQuery("DELETE FROM MyEntity m")
.executeUpdate()
;
But note, there is no grants that entity cache would be cleaned also. But for unit-test purposes it is look like good solution.
In my testing code I need to have a blank/empty database at each method.
I would run the test methods insider a transaction (and rollback at the end of each method). That's the usual approach. I don't see the point of committing a transaction and writing data to the database if you DELETE them just after. Just don't commit.
An alternative (not exclusive) would be to use DbUnit to put your database in a known state before a test execution. When doing this, you usually don't need to clean it up.
Another option would be to use raw JDBC to drop the database if exists and then have JPA recreate the whole database. Will be pretty slow though.