Spring.net + Nhibernate Integration Tests Pass When They Should Not - nhibernate

I'm using Spring.net with NHiberante (HibernateTemplate) to implement my DAO's.
I also have some integration tests, that extend from 'AbstractTransactionalDbProviderSpringContextTests '.
DI is working fine, and all test pass BUT sometimes they pass even when they shouldn't.
For example if my hbm.xml files have an error like this:
<class name="Confluence.Domain.User" table="THIS TABLE DOES NOT EXIST">
The tests fails, but if the error is like this one:
<many-to-many
class="Confluence.Domain.User"
column="THIS COLUMN DOES NOT EXIST"/>
the tests pass silently hiding the bug.
I'm testing it using SetComplete() and checking the DB for the changes, but I think the whole idea of this kind of tests is not to do so.
Can anyone tell me how to fix this issue?
Thank you very much!
#Ben: If I have to actually execute the SQL scripts to see if they work, what is the benefit of using this kind of Spring tests?

When testing your NH based DAO's you should flush the session so that the database is updated with the new information but still rollback as before. How to do this is explained here - http://forum.springframework.net/showthread.php?t=5246 I've added this to the reference docs. Hope this helps.
Cheers,
Mark

If you have a syntax error in your mapping, then NHibernate will fail on config.BuildSessionFactory()
But for mispelled/non-existence database objects, the only way for NHibernate to know is to actually run a query... So you might employ some integration tests to test insert/select on a single entity, to make sure it works.
Not sure what this has to do with Spring.NET though.

Related

How to prevent failure to provide Liquibase Context in PROD?

I have a huge concern about the Liquibase behavior of ignoring changeset Context if no context is supplied as a run-time parameter.
I'm setting up my first Liquibase project, using "dev, test, prod" as contexts in changesets. I'm passing in the context from a Spring Boot application.properties, which will have different versions for dev, test, etc. So the PROD version will have spring.liquibase.contexts=prod. So far, so good.
But what will happen if somehow, years from now, that line gets accidentally deleted, or commented out? Or what if someone happens to run Liquibase against PROD and doesn't supply "prod" as context?
It seems to me that ALL prior changesets NOT marked with "prod" will then run. This would include any marked just "test", that insert test data, or--God forbid--drop tables... Worse, they'll be running out of order.
I understand Liquibase DOES recommend including "test"-only changesets along with everything else, and using the "test" context (only) to distinguish them.
So. Am I right that this is a potential disaster waiting to happen? Is there a way to prevent this?
Thank you, StackOverflows!!
Yes, you are right that a potential disaster can happen. It could happen many other ways in your described process as well. This design is on purpose b/c most don't use contexts and so the majority want all changesets to run when you do an liquibase update.
A safety net I have seen at various places: Create a check for context around the liquibase command in your cicd automation instrumentation layer. For example those that use Jenkins, make sure there is a mandatory parameter for context before the build can even run.

Grails integration tests failing in a (seemingly) random and non-repeatable way

We are writing integration tests for our Grails 2.0.0 application with the help of the Fixtures and Buid-Test-Data plugins.
During testing, it was discovered that the integration test fail at certain times, and pass at other times. Running 'test-app' sometimes results in all tests passing, and sometimes results in some of our tests failing.
When the tests fail, they are caused by a unique constraint being violated during the insert of an instance of a domain class. This would indicate that there are still records in the test DB. I am running the H2 db, and have definitely got 'dbCreate = "create-drop"' in my DataSource.groovy.
Grails 2.0 integration test pollution? seems to indicate there is a significant test-pollution problem in Grails. Are there any solutions to this? Have I hit Grails-8530?
[Edit] the test-pollution seems to be caused by the unit tests. We have sort-of proved this by deleting the unit tests and successfully running 'test-app' repeatedly.
When I run into errors like this I like to try and find the unit test(s) that is causing the problem. This might be kinda tricky since yours seem to only be failing on occasion.
1) I'd look at unit tests that were recently added. If this problem just started happening then that's a good place to look.
2) Metaclassing seems to be good at causing these type of errors so I'd look for metaclassing that isn't setup/torn down properly. Not as much of an issue with 2.0 as with <= 1.3.7 but could be the problem.
3) I wrote a plugin that executes your tests in a random order. Which might not help you solve your current problem. But what might help you is it prints out all of your tests so you can take what it gives you and run grails test-app <pasted list of unit tests> IntegrationTestThatIsFailing then start removing unit tests to find the culprit(s). ( http://grails.org/plugin/random-test-order). I found a bug in this with 2.0 that I haven't had time to fix yet (integration tests fail when asserting on rendered view name) but it should still print out your test names for you (which is better than doing it yourself :)
The fact integration tests fail with a constraint violation due to existing records reminds me of a situation I once encountered with functional tests (selenium) executing in unpredictable order, some of them not cleaning up the database properly. Sure, the situation with functional tests is different, since it is more difficult to restore the database state (The testcase cannot rollback a transaction in another jvm).
Although integration tests usually roll back transactions, it is still possible to break this behavior if your code controls transactions (commits) explicitly.
First, I would try forcing execution order as mentioned by Jarred in 3). Assuming you can then reproduce the behavior, I would then check transactional behaviour next. Setting the logging level of org.hibernate.transaction to debug should show you where transaction boundaries are.
Sorry, don't yet have a good explanation why wiping out the unit tests helps getting rid of the symptoms besides a general "possibly metaclassing issues". :)

ISessionFactoryKeyProvider missing from CommonServiceLocator when upgrading NHibernate from 2.1 to 3.0

I have a ASP.NET MVC application that uses Spring.NET 1.2 for dependecy injection and NHibernate 2.1 for ORM. It has been running on MVC 3, using S#arp Architecture in a slightly modified version which we have been compiling ourselves, something I am now striving to get rid of. (I.e. I am going to start using referenced SharpArch .dlls instead of pure source code.)
The initialization of Spring is done using tips taken from here, as well as using the SpringServiceLocatorAdapter found here. NH is initialized using SharpArch's NHibernateSession.Init, which is given our two assemblypaths. The mapping is done with HBM XML files.
The decision to move to NH 3 led to a serious case of DLL Hell, due to which I of course had to update FluentNH, NH Validator, SharpArch, Spring, and Castle Windsor binaries. To get things working a lot of manual labor was needed, changing references and doing minor code fixes. This was all expected.
Now I've got the software running well enough that Spring is initialized and the DI done correctly. But when a repository tries using it's Session object, I get the following error.
Error creating object with name '' :
no services of type
'SharpArch.NHibernate.ISessionFactoryKeyProvider'
defined
I've been trying to figure out the cause of this for the best part of a day now.
It seems to me like SpringServiceLocatorAdapter is obsolete, but I can find no information regarding that. Also, simply removing the use of it results in repositories' Sessions being null and thus NullReferenceExceptions. But as far as I know the problem could just as well be the way NH is initialized.
Hopefully someone can point me in the right direction. I'm having a hard time since I'm not the one who setup the system to begin with, and lists of breaking changes for the version upgrades are hard to find.
Thanks a lot! I will of course provide more information if needed.
You need to register an implmentation of ISessionFactoryKeyProvider with spring, the default implementation is DefaultSessionFactoryKeyProvider, in windsor, the statement would look like this:
container.Register(
Component.For(typeof(ISessionFactoryKeyProvider))
.ImplementedBy(typeof(DefaultSessionFactoryKeyProvider))
.Named("sessionFactoryKeyProvider"));

What is the NHibernate Mapping.ByCode equivalent of the "hbm2ddl.keywords" setting?

I just ran into a situation related to this SO question: How to tell NHibernate always to force quoted identifiers?
My entity has an "Order" property, and NH chokes trying to create the database. I am using the new Mapping.ByCode feature of NHibernate 3.2, and its not entirely clear where I need to apply the hbm2dll.keywords setting.
Thanks in advance!
Ah, found it: http://nhforge.org/blogs/nhibernate/archive/2009/06/24/auto-quote-table-column-names.aspx
When you have an instance of a configured configuration (just before call BuildSessionFactory) you can execute:
SchemaMetadataUpdater.QuoteTableAndColumns(configuration);

Entity Validation in Sharp Architecture Repository

I have created a new 1.6 Sharp Architecture project.
I have marked my only Entity with HasUniqueDomainSignatureAttribute and one string property marked DomainSignatureAttribute.
I create 2 entities with the same DomainSignature and I'm able to save them both thous having duplicates.
Am I missing some configuration? As I was under the impression that this would work out of the box.
Before saving you should manually check entity for validness. I don't know how it is done now, but in previos versions each entitity had a property IsValid.
Well yes, the Validation method IsValid() is on the Entities.
But from the documentation I get the impression that if using NHibernate and NHibernate.Validators the repositories should validate the entities before Insert and Update.
As in the documentation on nhforge.org
In SharpArch.Data.NHibernate.NHibernateSession following snippet is called each time Init() is used.
Those things make me wonder why it doesn't work.
I could roll my own, but that seems like waste if it's already there.
Can anyone point me in the right direction? Also the SchemaExport util should use the validators when generating the scripts.