5

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:来自表文档的关联指的是未映射的类:用户... 25 更多 2009-11-11 23:52:58,933 [main] 错误 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:

但是在这种情况下,我想要允许任何用户拥有文档的多态效果,同时强制系统的每个用户都适合定义的角色之一。因此,不应直接实例化 User 并使其抽象化。

我不想为非抽象用户类中的角色使用枚举,因为我希望能够为不同的角色添加额外的属性,这在某些情况下可能没有意义(我不想有角色设置为 RegularEmployee 的单个用户,以某种方式获得非空 managedGroup)。

这是Grails中的错误吗?我错过了什么吗?

4

2 回答 2

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]
}

不过,我认为您不会在当前的域映射中获得所需的内容。

于 2009-11-12T14:44:01.380 回答
2

前几天我们正在测试 grails 继承层次结构以查看多态性。我们发现了以下场景:

抽象超类 - 子类继承父类的行为,但父类不能用于引用要存储在数据库中的子类。

tablePerHeirarchy 为 false 的超类 - 子类将父类的字段存储在父类的表中,多态性按预期工作。

带有 tablePerHeirarchy false 的空超类 - 子类将所有自己的数据存储在它们的表中,多态性按预期工作。

因此,在您的情况下,如果您要从用户类中删除 abstract 关键字,那么一切都会按预期工作。唯一的缺点是所有 User 字段都存储在 User 表中,而 RegularEmployee 表中只有 id 和 version 列,而 Manager 表中只有对 Workgroup 行的引用。

于 2009-11-13T01:32:36.787 回答