Hibernate4 plugin - hibernate.cfg.xml from plugin overwrites local file

classic Classic list List threaded Threaded
4 messages Options
Reply | Threaded
Open this post in threaded view
|

Hibernate4 plugin - hibernate.cfg.xml from plugin overwrites local file

keithrz
Hibernate4 plugin version: 4.1.11.4 (also tried 4.1.11.7 with same result)
Grails version: 2.3.4

Running "clean" wipes out <my work folder>/resources/hibernate.cfg.xml, as it should.  Running an integration test will recreate this file.

About half the times that hibernate.cfg.xml is recreated, it is a copy of my grails-app/conf/hibernate/hibernate.cfg.xml.  The other half it is nearly empty - it is an exact copy of the hibernate.cfg.xml file contained within the Hibernate4 plugin (src/java/hibernate.cfg.xml).

When the Hibernate4 file is copied into my work folder, all my integration tests fail, of course, because the domain classes listed in my hibernate.cfg.xml file are not in the working hibernate.cfg.xml file and are not treated as Grails domain classes.

My tests started failing after upgrading to Grails 2.3.4 + Hibernate4 (from Grails 2.2.4 + Hibernate 2.2.4).  I originally thought that I fixed my integration tests by adding "mapping package=" tags into my hibernate.cfg.xml file (previously, the file only had "mapping class=" tags.)  But I guess that my tests worked after that change because I had simply modified hibernate.cfg.xml in some way, which caused the file to get picked up that time.

It seems like there is a race condition going on when Grails copies this file after a clean.  If I modify my local file after a clean, the file gets copied over and everything works.

FYI, my work directory is specified in BuildConfig.groovy as "work"
grails.project.work.dir = "work"

I should be able to get around this by creating a script that does the following (in order):
1. clean
2. "touch" my local hibernate.cfg.xml file
3. test-app

Should I log this as a Jira bug against Jira project GPHIB?
Reply | Threaded
Open this post in threaded view
|

Re: Hibernate4 plugin - hibernate.cfg.xml from plugin overwrites local file

keithrz
I can see how this can happen in GrailsProjectPackager.groovy.  packagePlugins() is run in a multi-threaded fashion.

My current workaround is to add a "CleanTestApp" script.

includeTargets << grailsScript("_GrailsClean")
includeTargets << grailsScript("RefreshDependencies")
includeTargets << grailsScript("TestApp")

target(cleanTestApp: "Clean, refresh dependencies, then test app") {
        depends(cleanAll, refreshDependencies, packagePlugins, copyHibernateCfg, 'default')
}

target(copyHibernateCfg: "Copy the local hibernate.cfg.xml file to work dir after plugins packaged") {
        copy(file: "${basedir}/grails-app/conf/hibernate/hibernate.cfg.xml",
             tofile: "${grailsSettings.resourcesDir}/hibernate.cfg.xml", overwrite: true)
}

setDefaultTarget("cleanTestApp")


The problem with this fix is that it only works when running clean-test-app.  I want to always copy the hibernate.cfg.xml immediately after the packages are exploded out in the work dir.  I'd like to do something like this in _Events.groovy:
eventPackagingEnd = { ->
    AntBuilder ant = getAnt()
    ant.copyfile(src: "${buildSettings.baseDir}/grails-app/conf/hibernate/hibernate.cfg.xml",
                 dest: "${buildSettings.resourcesDir}/hibernate.cfg.xml",
                 forceoverwrite: true)
}

but the PackagingEnd event is not fired when running tests.  The real problem seems to be...

THERE ARE SO FEW EVENTS TO LISTEN TO!  Ideally, each and every target specified in the build scripts would have an event that automagically triggered once the target finished.

Reply | Threaded
Open this post in threaded view
|

Re: Hibernate4 plugin - hibernate.cfg.xml from plugin overwrites local file

keithrz
I ended up listening to the "CompileEnd" event.  Here is my code:
eventCompileEnd = {
    if(buildSettings.baseDir.getPath().endsWith('myproject-core')) {
        ant.copyfile(src: "${buildSettings.baseDir}/grails-app/conf/hibernate/hibernate.cfg.xml",
                     dest: "${buildSettings.resourcesDir}/hibernate.cfg.xml",
                     forceoverwrite: true)
    }
}

The if statement makes sure that this is only run if the current module/plugin being compiled is myproject-core, which is the module containing the domain classes & hibernate.cfg.xml file.  This check is needed because this eventCompileEnd listener will run any time any module in my project is compiled.

Reply | Threaded
Open this post in threaded view
|

Re: Hibernate4 plugin - hibernate.cfg.xml from plugin overwrites local file

keithrz
Logged an issue in Jira:
http://jira.grails.org/browse/GPHIB-14