Hi Guys,
I'm busy generating a little how-to of "this in hibernate" becomes "this in GORM DSL", but I'm a bit stuck when it comes to natural keys (where I don't have a surrogate id key, just a plain 'ol string key).
Consider my Branch (as in a Branch of a Bank) object:
class Branch {
String name // my natural key
// other fields
static mapping = {
table 'BK_BRANCH'
version false
name column: 'BRANCH_NM'
// other fields...
}
}
Of course, starting that bad boy up will complain about the lack of an id field...
org.hibernate.HibernateException: Missing column: id in PUBLIC.BK_BRANCH
Makes sense. I'm missing my natural key mapping. The way I'd map the natural key in hibernate is something like:
<class name="Branch" table="BK_BRANCH" >
<id name="name" column="BRANCH_NM">
<generator class="assigned"/>
</id>
// and more mappings here....
</class>
And if I use a hibernate file to do my mapping, this works just fine and life is good. Dynamic finders are happy. Skies are sunny. But... I want to use GORM DSL for this demo, so that's not an option for me...
So I guess I could try using some kind of id assignment...
id generator:'assigned', column: "BRANCH_NM"
But then I have duplicate mappings on the same column... and am subsequently slapped...
Repeated column in mapping for entity: com.grailsinaction.legacy.db.Branch column: BRANCH_NM (should be mapped with insert="false" update="false")
Which is not ideal. And I don't care to have an id field at all, so that doesn't seem like the right approach anyway...
So... I think what I want is something like:
id generator:'assigned', column: "BRANCH_NM", name: 'name'
And then not have a separate mapping for my "name" field ... I suspect that that HibernateMappingBuilder is not too excited about changing the name of the id field from the default.
Anyone done any natural key mappings in the GORM DSL without an id field?
Ideas welcome...
Glen.
[b]解决方法[/b]
I got it to work, but it's not particularly groovy:
class Branch {
String id
static transients = ['name']
void setName(String name) {
id = name
}
String getName() {
return id
}
static mapping = {
table 'BK_BRANCH'
version false
id generator: 'assigned', column: 'BRANCH_NM'
}
}
Basically it just allows you to work with the 'name' attribute but it's just a wrapper around the real 'id' attribute.
[b]One gotcha - to save new instances, you need to call save(insert: true) otherwise the insert fails since it seems to see that the id is assigned and assumes it's an update. This is probably due to calling saveOrUpdate() under the hood, which uses null/non-null PK as the flag to determine whether to call save() or update().[/b]
转自:http://grails.1312388.n4.nabble.com/GORM-DSL-mappings-for-natural-keys-and-no-surrogate-quot-id-quot-field-td1358790.html
I'm busy generating a little how-to of "this in hibernate" becomes "this in GORM DSL", but I'm a bit stuck when it comes to natural keys (where I don't have a surrogate id key, just a plain 'ol string key).
Consider my Branch (as in a Branch of a Bank) object:
class Branch {
String name // my natural key
// other fields
static mapping = {
table 'BK_BRANCH'
version false
name column: 'BRANCH_NM'
// other fields...
}
}
Of course, starting that bad boy up will complain about the lack of an id field...
org.hibernate.HibernateException: Missing column: id in PUBLIC.BK_BRANCH
Makes sense. I'm missing my natural key mapping. The way I'd map the natural key in hibernate is something like:
<class name="Branch" table="BK_BRANCH" >
<id name="name" column="BRANCH_NM">
<generator class="assigned"/>
</id>
// and more mappings here....
</class>
And if I use a hibernate file to do my mapping, this works just fine and life is good. Dynamic finders are happy. Skies are sunny. But... I want to use GORM DSL for this demo, so that's not an option for me...
So I guess I could try using some kind of id assignment...
id generator:'assigned', column: "BRANCH_NM"
But then I have duplicate mappings on the same column... and am subsequently slapped...
Repeated column in mapping for entity: com.grailsinaction.legacy.db.Branch column: BRANCH_NM (should be mapped with insert="false" update="false")
Which is not ideal. And I don't care to have an id field at all, so that doesn't seem like the right approach anyway...
So... I think what I want is something like:
id generator:'assigned', column: "BRANCH_NM", name: 'name'
And then not have a separate mapping for my "name" field ... I suspect that that HibernateMappingBuilder is not too excited about changing the name of the id field from the default.
Anyone done any natural key mappings in the GORM DSL without an id field?
Ideas welcome...
Glen.
[b]解决方法[/b]
I got it to work, but it's not particularly groovy:
class Branch {
String id
static transients = ['name']
void setName(String name) {
id = name
}
String getName() {
return id
}
static mapping = {
table 'BK_BRANCH'
version false
id generator: 'assigned', column: 'BRANCH_NM'
}
}
Basically it just allows you to work with the 'name' attribute but it's just a wrapper around the real 'id' attribute.
[b]One gotcha - to save new instances, you need to call save(insert: true) otherwise the insert fails since it seems to see that the id is assigned and assumes it's an update. This is probably due to calling saveOrUpdate() under the hood, which uses null/non-null PK as the flag to determine whether to call save() or update().[/b]
转自:http://grails.1312388.n4.nabble.com/GORM-DSL-mappings-for-natural-keys-and-no-surrogate-quot-id-quot-field-td1358790.html