Tuesday, May 5, 2009

Grails Persistence with GORM & GSQL

A couple days ago I received the Grails Persistence with GORM and GSQL by Robert Fisher published by APress http://apress.com/book/view/1430219262.

At first I was surprised that it was a total of 156 pages (I was pleased that I didn't have to work my way through yet another 700 page book).

As the title indicates this is focused on one of the greatest assets of Grails, GORM. When working with GORM, you really need examples and options to help you with common data query and dataset organization tasks, this book provides that.

In a nutshell, if you are working on a Grails project, this book will provide you with a concise reference with great code examples of valuable GORM features that you will refer back to.

Introduction to Grails Course

Chariot Solutions is offering a 1 day Introduction to Grails course see: http://chariotsolutions.com/learn/intrograils for details.

Monday, January 26, 2009

Groovy and Grails Magazine

I just started reading the Groovy and Grails magazine and I would highly recommend it for Groovy and Grails enthusiasts.

Check it out at http://groovymag.com

Monday, January 12, 2009

Philadelphia Emerging Tech Conference

Checkout the Philadelphia Emerging Technology Conference
March 26-27, 2009
http://www.phillyemergingtech.com/

Jeff Brown from SpringSource will be speaking:
Co-Author, The Definitive Guide To Grails Second Edition

Wednesday, August 27, 2008

Acegi and Groovy Class Packages

With all of the tutorials and examples for Grails there is often no reference to packaging your Groovy classes.

So, I decided to convert all of my project into packages including Acegi.

Using IntelliJ 7.04 & JetGroovy plugin v1.6.18593, I was able to refactor most of my classes without issue. Service classes required me to add the imports manually... no problem there. Of course its odd that I had to manually add imports to java.util.*

Acegi classes required to add the package to the class declaration within grails-app/conf/SecurityConfig.groovy

loginUserDomainClass = "com.mycorp.projname.security.User"
authorityDomainClass = "com.mycorp.projname.security.Role"
requestMapClass = "com.mycorp.projname.security.Requestmap"

(thanks to Burt Beckwith)

Friday, August 22, 2008

Grails on WebLogic - Validation Errors

If you are deploying Grails on WebLogic 9/10 you must ensure that all of your domain classes MUST implement Serializable. If not, you won't see validation feedback on your form.

Also, as part of the standard Java Serializable interface, ensure that all members of the domain class must also be Serializable.

You will see a WebLogic log message:

<[weblogic.servlet.internal.WebAppServletContext@f7ca6d - appName: '_appsdir_MyApp_dir',

name: 'MyApp', context-path: '/MyApp'] could not deserialize the request scoped attribute with name: "org.codehaus.groovy.grails.ERRORS_MyDomainObj_19315431"
java.io.NotSerializableException: org.springframework.beans.factory.support.DefaultListableBeanFactory
at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1081)
at java.io.ObjectOutputStream.defaultWriteFields(ObjectOutputStream.java:1375)
at java.io.ObjectOutputStream.writeSerialData(ObjectOutputStream.java:1347)
at java.io.ObjectOutputStream.writeOrdinaryObject(ObjectOutputStream.java:1290)
at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1079)
Truncated. see log file for complete stacktrace

Friday, July 18, 2008

Acegi Table Configuration

One of the main issues I had from the Grails site was using the often reserved words "user" and "role" for the main table names.

While I was working with Oracle, "user" was an issue but "role" was not. So, generated user but mapped to a table called "app_user".

Behind the scenes I had 4 tables:
1. app_user
2. role
3. role_app_user
4. requestmap

Also, generated a sequence called hibernate_sequence

I ran into intermittent problems where hibernate would not be able to identify the intersection table "role_app_user".

I decided to rename the "role" table to "app_role" and tell Grails the specific name of the intersection table. By adding the table name and the "joinTable" option to the mapping, we identify the link between the classes and their intersection table.

File: Role.groovy
class Role {
static hasMany = [people: User]

String description
String authority = 'ROLE_'

static constraints = {
authority(blank: false)
description()
}

static mapping = {
table "app_role"
people joinTable:[name:'ROLE_APP_USER', key:'id', column:'people_id']
}

}

File: User.groovy
class User {
static transients = ['pass']
static hasMany = [authorities: Role]
static belongsTo = Role

String username
String userRealName
String passwd
boolean enabled
String email
boolean emailShow
String description = ''
String pass = '[secret]'

static constraints = {
username(blank: false, unique: true)
userRealName(blank: false)
passwd(blank: false)
enabled()
description (nullable: true)
}

static mapping = {
table "app_user"
authorities joinTable:[name:'ROLE_APP_USER', key:'id', column:'authorities_id']
}
}

In preparation of moving this code to testing and production regions describe (Oracle's "desc object") to extract the tables and sequence for your DBA's convenience.