我有两个班级:
用户
class User {
//relationships. . . .
static belongsTo = [ company : Company, role : Role ]
static hasMany = [ holidays : Holiday ]
String login
String password
static constraints = {
login(unique:true,size:6..15)
}
String toString() {
this.login
}
}
还有另一个这样的课程:
角色:
class Role {
String roleName
String privilege
static hasMany = [ user : User ]
static constraints = {
privilege(nullable:true)
roleName(unique:true)
}
String toString() {
this.roleName
}
}
我写了这样的集成测试:
def user1 = new User(login:"aravinth", password:"secret")
def user2 = new User(login:"anto", password:"secret")
def user3 = new User(login:"antoa", password:"secret")
def role1 = new Role(roleName:"manager").save()
def role2 = new Role(roleName:"devleoper").save()
role1.addToUser(user1)
role1.addToUser(user2)
role2.addToUser(user3)
assert "manager" == user1.role.roleName
此测试工作正常。但是,当我将以下行添加到上面的测试代码中时:
def roleMembers = Role.findByRoleName("manager")
我收到的错误是这样的:
null id in mnm.schedule.User entry (don't flush the Session after an exception occurs)
org.hibernate.AssertionFailure: null id in mnm.schedule.User entry (don't flush the Session after an exception occurs)
at org.grails.datastore.gorm.GormStaticApi.methodMissing(GormStaticApi.groovy:108)
at mnm.schedule.RoleItntegrationTests.testAddingRolesToUser(RoleItntegrationTests.groovy:44)
怎么回事?我哪里错了?
我正在使用Grails 2.0。
提前致谢。
答案 0 :(得分:10)
您收到此错误的原因是,当执行语句Role.findBy静态方法时,Hibernate(由Grails GORM使用)检查是否需要“autoFlush”。由于存在新的临时Role对象,Hibernate会尝试自动刷新会话。但是,此时存在尚未与角色关联的新用户对象(在用户域中不可为空)。因此,在刷新时,用户对象不会通过验证,因此具有异常提及的空id。
解决此问题的方法是在开始创建/更新相同类型的实体之前,使所有数据库读取调用(例如findBy方法)。
另一个选项(虽然不是很好)是设置会话刷新模式手册。
User.withSession{ sessionObj ->
sessionObj.setFlushMode(FlushMode.MANUAL);
//put your Role.findBy mthod call here
sessionObj.setFlushMode(FlushMode.AUTO);
}
答案 1 :(得分:0)
如果您使用的是Spring Security Core,如果添加约束size
或创建自定义validator
以检查“密码”是否等于“确认密码”,则会出现同样的错误。解决方案是在这些情况下使用命令对象。此案例已解决here。
一般情况下,如果某些字段为null,则该错误可能会发生,因为它不应为null,但它会传递约束(通常是因为代码中有一些错误)。数据库具有非空规则,因此不会创建该条目。 Grails会显示那个丑陋的错误。