Tuesday, May 6, 2008

Composite Key in Domain Class

Using the default id column in the database works great. However, if you are facing a "legacy" database design and unable to alter the table definition, you have a bit of work to do.

Defining your domain class:
1. The class must implement Serializable
class MyClass implements Serializable {
...
static mapping = {
table "my_table"
version false
id composite: ["myFieldOne","myFieldTwo"]
...

2. The scaffolding will by default setup all communication via the id column. The id column in this case is a serialized value. However, there is an issue with Grails v1.0.2 that does not deserialize the value properly. So, for now you have to work around using the primary key:

3. Add new Method to domain class - define a map of the values
def getPK ( ) {
["myFieldOne":myFieldOne, "myFieldTwo":myFieldTwo]
}


4. List view - Add a link on the page to show details for the current record

<span class="actionButton">
<g:link action="show" params="${myClass.getPK()}">Detail </g:link>
</span>

NOTE: "id=" was changed to "params=" and you are passing in the map returned from myClass.getPK()

5. MyClassController.groovy - modify the retrieval code in the show method
def show = {
def myClass = MyClass.get( new MyClass(params) ) //here are your inbound params

if(!myClass) {
flash.message = "MyClass not found with ${params}"
redirect(action:list)
}
else { return [ myClass: myClass] }
}

5 comments:

Anonymous said...

Thanks, great article.
But I have been having difficulty adding new records. I always end up with grails complaining about not fining an element with empty id.

Denis Wang said...

Somehow I got null on the step 5: new MyClass(params). Any idea how to fix this problem?
Thanks.
Denis

Lo said...
This comment has been removed by the author.
Sakthi Saravanakumar said...

I got the same Null pointer Exception error in the View.

myclass = Myclass.get(new Myclass(params))

So I need your help.

Unknown said...

Great works perfectly!