Grails GORM不会将抽象域类持久保存到数据库中,从而导致多态关系中断。例如:
abstract class User {
String email
String password
static constraints = {
email(blank:false, nullable:false,email:true)
password(blank:false, password:true)
}
static hasMany = [membership:GroupMembership]
}
class RegularEmployee extends User {}
class Manager extends User {
Workgroup managedGroup
}
class Document {
String name
String description
int fileSize
String fileExtension
User owner
Date creationTime
Date lastModifiedTime
DocumentData myData
boolean isCheckedOut
enum Sensitivity {LOW,MEDIUM,HIGH}
def documentImportance = Sensitivity.LOW
static constraints = {
name(nullable:false, blank:false)
description(nullable:false, blank:false)
fileSize(nullable:false)
fileExtension(nullable:false)
owner(nullable:false)
myData(nullable:false)
}
}
原因
引起:org.hibernate.MappingException:来自的关联 表文档是指未映射的类:User ... 25更多2009-11-11 23:52:58,933 [主要]错误mortbay.log - 嵌套在org.springframework.beans.factory.BeanCreationException:创建名为'messageSource'的bean时出错:bean的初始化 失败;嵌套异常是 org.springframework.beans.factory.BeanCreationException:错误 创建名为'transactionManager'的bean:无法解析引用 设置bean属性'sessionFactory'时bean'sessionFactory'; 嵌套异常是 org.springframework.beans.factory.BeanCreationException:错误 创建名为'sessionFactory'的bean:调用init方法 失败;嵌套异常是org.hibernate.MappingException:An 表文档中的关联是指未映射的类:用户: org.hibernate.MappingException:表文档中的关联 指未映射的类:用户
但在这种情况下,我希望允许任何用户拥有文档的多态效果,同时强制系统的每个用户都适合其中一个已定义的角色。因此,用户不应该直接实例化并且是抽象的。
我不想在非抽象的User类中使用enum作为角色,因为我希望能够为不同的角色添加额外的属性,这在某些情况下可能没有意义(我不知道)想让一个角色设置为RegularEmployee的用户以某种方式得到一个非空的managedGroup。)
这是Grails中的错误吗?我错过了什么吗?
答案 0 :(得分:3)
您可能希望查看Shiro,Nimble(使用Shiro)和/或Spring Security插件的域模型。他们创建一个具体的用户域和一个具体的角色域。 Shiro特别为多对多映射创建UserRole域。
然后在您的角色域中,您可以添加所需的任何属性。如有必要,您可以创建一个单独的域以允许任意属性,如:
class Role {
//some properties
static hasMany = [roleProperties:RoleProperty, ...]
}
class RoleProperty {
String name
String value
static belongsTo = [role:Role]
}
我认为你不会在当前的域映射中找到你想要的东西。
答案 1 :(得分:2)
我们前几天正在测试grails继承heirarchy以查看多态性。我们发现了以下场景:
Abstract Superclass - 子类继承父类的行为,但父类不能用于引用要存储在数据库中的子类。
带tablePerHeirarchy的超类false - 子类将父项的字段存储在父表中,多态性按预期工作。
使用tablePerHeirarchy false的空超类 - 子类将所有自己的数据存储在表中,多态性按预期工作。
因此,在您的情况下,如果您要从用户类中删除abstract关键字,一切都将按预期工作。唯一的缺点是所有用户字段都存储在User表中,而RegularEmployee表只包含id和version列,而Manager表只有对Workgroup行的引用。