Grails Next Impressions - Some Problems
After working with Grails a bit more after my original post, I've come across some rather annoying issues.
First up is an issue with the domain classes. I've noticed that if you have constraints defined which are invalid or whose value is incorrect, no error is reported. Oddly enough, what does occur is that the tables aren't created, and the class isn't initialized, so any subsequent attempt to use that class with result in a class definition not found exception. This is a poor choice of handling such a fundamental problem.
Next up was the gant scripts, which are presumably Grails' answer to Ruby on Rails rake tasks. The problem however, is that the grails environment isn't loaded and initialized for the gant script. This means that to do something as simple as accessing a domain class in a gant script requires massive amounts of coding:
import org.springframework.orm.hibernate3.* includeTargets << grailsScript('Bootstrap') target(main: "Bootstraps the database - assumes an empty database!") { depends(configureProxy, packageApp, classpath) bootstrap() def countryClass = grailsApp.getDomainClass('com.csam.remotecron.Country').getClazz() def template = new HibernateTemplate(appCtx.getBean("sessionFactory")) if (!countryClass.findById('CA')) { def canada = countryClass.newInstance() canada.id = 'CA' canada.englishName = 'Canada' canada.localName = 'Canada' template.save(canada) } } setDefaultTarget(main)
This, quite frankly, is absurd. Anyone who knows me knows that I am no fan or Ruby on Rails, but the rake tasks seem vastly superior to gant.
The problem is even more apparent if you try to use gant to prepopulate your database. It is common in very script systems to have "validation" data in the database, such as valid countries, primary administrative subdivisions, etc., etc. Ruby on Rails can use fixtures to do this, in either YAML or CSV format. There is a fixtures plugin for Grails, but it doesn't support CSV (for large datasets, this becomes a problem), and since the Grails environment isn't even initialized in gant, you cannot access the fixtures plugin, anyway.
Grails does have a "BootStrap" class, but this is really infeasible, as it runs every single time the application is deployed, which means (for example) that your entire country database must be re-created. If you are using referential integrity in your database, this is a real problem.
I've spent two days now trying to resolve this problem, with absolutely no solution in sight. Seems more like I will have to make a custom gant script which will at least initialize the GORM engine, and some kind of custom CSV reader.
Comments
Hi,
Grails 1.2 introduces the idea of failOnError, which does throw an exception when your save fails. People have been confused by this behaviour and it's being addressed.
This at least solves one problem you mentioned.
http://www.grails.org/1.2-M2+Release+Notes.
The Build Test Data plugin introduces a much more forgiving creation mechanism for grails, you might want to take a look at that.
We have used the Bootstrap mechanism within Grails to load validation data at startup. It was just a matter of doing a check to see if the data we were inserting already exists. Seems weird to me to completely dismiss this mechanism.
If you insist on using Gant, why not just use Groovy's Built in SQL support and invoke a table creation script. After all, there are surely much more robust tools out there that will let you insert a whole bunch of data into a database.
( http://docs.codehaus.org/display/GROOVY/Tutorial+6+-+Groovy+SQL )
Other plugins you might find useful are GORM Labs ( run raw sql ) and Datasources ( use multiple databases ).
In my experience, GORM is a nice wrapper around Hibernate, but the beauty of Grails and Groovy is that you have the option to not use them and rely on more powerful tools.
Thanks for the info, Tomas - I will certainly look into this.
Add comment
Visit my Friends and Family
If you've enjoyed my site, please take a moment to visit my friends and family, many of whom have some interesting insights, and entertaining thoughts and ideas.
- Crause Family - the family website
- Peter Crause - my father
- Justin Crause - my brother
- Cencina Photomagic - great photographer
- Shawn Adrian - talented graphic designer, bad driver, and all-round fun guy