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)
Showing posts with label composite key. Show all posts
Showing posts with label composite key. Show all posts
Thursday, May 8, 2008
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] }
}
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] }
}
Subscribe to:
Posts (Atom)