I have two classes :
User
class User {
//relationships. . . .
static belongsTo = [ company : Company, role : Role ]
static
If you are using Spring Security Core, the same error occurs if you add the constraint size
or you create a custom validator
to check if a "password" is equal to a "confirm password". The solution is to use a command object in these cases. This case is solved here.
In general, this error could happen if some of the fields is null when it should not be null, but it pass the constraint (usually because some error in the code). The database has a not null rule so the the entry won't be created. Grails will show that ugly error then.
The reason that you are getting this error is that when the statement Role.findBy static method is executed, Hibernate(which is used by grails GORM) checks whether "autoFlush" is required. Since new transient Role objects are present, Hibernate tries to automaically flush the session. However at this point the new user objects are present which haven't yet been associated with a role (which is not nullable in User domain). Therefore while flushing, the user object doesn't pass the validation and hence has a null id as mentioned in the exception.
The way to solve this would be to make all the DB read calls (such as findBy methods) before you start creating/updating entities of the same type.
Another option (although not a very good one ) is to set the session flush mode manual.
User.withSession{ sessionObj ->
sessionObj.setFlushMode(FlushMode.MANUAL);
//put your Role.findBy mthod call here
sessionObj.setFlushMode(FlushMode.AUTO);
}