Showing posts with label composite key. Show all posts
Showing posts with label composite key. Show all posts

Thursday, May 8, 2008

Composite Key in Domain Class - round 2

Still tinkering with the composite key issues.

I changed my previous approach a bit, I now define my own getId and setId methods to essentially serialize and deserialize the the key fields strung together

Created a delimiter
static final String delimiter = '~@'

Defined (overriding default) accessors:
def getIdAsMap() {
["fieldOne": fieldOne, "fieldTwo": fieldTwo]
}

def getId() {
fieldOne + delimiter + fieldTwo
}

def setId(String inString) {
def fieldList = new ArrayList()
def items = inString.split(delimiter)
items.each { fieldList.add (it) }
this.setFieldOne (fieldList[0])
this.setFieldTwo (fieldList[1])
getIdAsMap()
}

Its a little clunky but when you can pass around the map, use getIdAsMap(), in other cases the String is available with myclass.id


Inserting new rows requires a little tweak, by default with version: false set, GORM will try to perform a sql update on new records. To fix this, add insert:true to your save method

myClass.save(insert: true)

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] }
}