String IDs in grails - how exactly can it be done?
Can somebody show me clear, complete, 100% working way to set string-typed field 开发者_如何学Pythonas ID in grails? I've read the docs, then read all similar ranting on the web, but failed to create a working prototype.
Here is one of my attempts to make you believe I'm not just lazily waiting for somebody to do the job )))
class User {
String login
static hasMany = [apps : Application]
static constraints = {
}
static mapping = {
id generator: 'assigned', name: "login"
}
}
When you use a natural id you have to use the findBy method instead of the get method as demonstrated in this test:
def user = new User(login: "test")
assertNotNull user.save(flush: true)
user = User.findByLogin("test")
assertNotNull user
assertEquals "test", user.login
Alternately you could use a single field composite id mapping:
class User implements Serializable {
String login
static hasMany = [apps: Application]
static constraints = {
}
static mapping = {
id composite: ['login']
}
}
Note that composite id domain classes are required to implement Serializable.
The test for the composite id would be:
def user = new User(login: "test")
assertNotNull user.save(flush: true)
user = User.get(new User(login: "test"))
assertNotNull user
assertEquals "test", user.login
I'm assuming you are talking about mapping a String primary key (normally a natural key) to the primary key in a grails domain object.
This answer is derived from information found here: http://dsommerville.blogspot.com/2009/09/mapping-natural-keys-using-gorm.html and here: http://gr8fanboy.wordpress.com/2010/04/08/adding-a-natural-key-to-a-database-table-using-straight-gorm/
For example, you have a table Users defined with the following schema:
username varchar(40) not null pimary key,
firstname varchar(40) not null,
lastname varchar(40) not null
To do this in grails, you have to massage the definition a little.' First, you have to map the id to the given column in your database. With a generator "assigned"
Then, for usability, you may want to add the transient field username so that you can use user.username = . Otherwise, I believe you'd have to access the field using id. The getter and setter for this transient property set the appropriate "id" field, which in turn updates the database.
class User {
String id
String password
String fullName
static transients = ['username']
static constraints = {
id(unique:true,blank:false)
password(nullable:true,maxSize:20)
fullName(nullable:true,maxSize:20)
}
static mapping = {
table 'users'
id column: 'username', generator: 'assigned'
version false
}
//
void setUsername(String username) {
id = username
}
String getUsername() {
return id
}
}
Note: Scaffolding doesn't recognize the transient field, so you'll have to work the generated controllers/views if you want your code to more closely model your db.
精彩评论