Why is uniquely constrained field failing on updat

2019-04-24 12:39发布

问题:

When i have a custom identity attribute mapped in a domain class, why does hibernate check for unique constraint? When i update an object, the validation fails despite the fact that the posted field value is the same as that stored in DB! This occurs, even if I make no change to the form (ensuring dirty: false and no property binding errors). I have a Grails domain class like below:

class User {
  Long profileId
  String email
  String username
  String password
  String title
  String firstname
  String lastname
  String zipCode
  Date lastLoginDate

  static constraints = {
      profileId nullable: true, blank: true
      email blank: false, unique: true, email: true
      username blank: false, unique: true
      password blank: false
      lastLoginDate nullable: true

      firstname nullable: true
      lastname nullable: true
      zipCode nullable: true
  }

  static mapping = {
    table 'USER_PROFILE'
    id name:"profileId", column: "profile_id", generator: "sequence", params: [sequence:'userprofile_sequence']
    version false
  }

}

Now, when i create a user with minimum attribute set, a record is created. But when i try to update the same object like: def user = User.findByUsername('akeel') user.lastLoginDate = new Date() user.save(flush: true) Nothing happens, because unique validation check fails. I can bypass the validation by doing user.save(validate: false, flush: true) But, that's not an option, as i need to validate the zipCode, whenever a user adds it.

I had to set the constraint for the custom identity column, profileId, as nullable true, to resolve the 'repeated column in mapping' problem as proposed as suggested here.

This question is exactly like the one discussed here, but the solutions proposed didn't work for me.

I am using grails 2.1.2, let me know if anything else is required to understand the problem.

回答1:

It seems that a custom property name for the primary key doesn't work in Grails. I've tested with Grails 2.0.4, 2.2.4 and 2.3.4 and they all fail to recognise profileId as the primary key. User.get(1) works fine, but user.ident() returns null. I would certainly raise an issue in the Grails JIRA.

The simplest solution is to remove the profileId property and just use the builtin id instead. Then just remove the name: value from the custom mapping. In other words, you should end up with

id column: "profile_id", generator: "sequence", params: [sequence:'userprofile_sequence']