代码之家  ›  专栏  ›  技术社区  ›  Visionary Software Solutions

GORM关系中的抽象类

  •  5
  • Visionary Software Solutions  · 技术社区  · 15 年前

    GrailsGorm不会将抽象域类持久化到数据库中,从而导致多态关系中断。例如:

    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.mappingeexception引起:来自 表文档引用了未映射的类:用户 ……25更多2009-11-11 23:52:58933[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: 表文档中的关联引用了未映射的类:用户: org.hibernate.mappingexception:表文档中的关联 引用未映射的类:用户

    但是在这个场景中,我希望允许任何用户拥有一个文档,同时强制系统的每个用户适应其中一个定义的角色的多态效果。因此,不应该直接实例化用户,而是将其抽象化。

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

    这是圣杯里的虫子吗?我错过什么了吗?

    2 回复  |  直到 13 年前
        1
  •  3
  •   Matt Lachman    15 年前

    您可能希望查看Shiro、Nimble(使用Shiro)和/或Spring安全插件的域模型。它们创建一个具体的用户域和一个具体的角色域。Shiro特别为多对多映射创建了一个用户角色域。

    然后,在角色域中,可以添加所需的任何属性。如有必要,您可以创建一个单独的域以允许任意属性,如:

    class Role {
        //some properties
        static hasMany = [roleProperties:RoleProperty, ...]
    }
    
    class RoleProperty {
        String name
        String value
        static belongsTo = [role:Role]
    }
    

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

        2
  •  2
  •   Blacktiger    15 年前

    前几天我们在工作中测试了圣杯继承继承权,以研究多态性。我们发现了以下情况:

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

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

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

    因此,在您的例子中,如果您使从用户类中删除抽象关键字,那么一切都将按预期工作。唯一的缺点是,所有的用户字段都存储在用户表中,只留下RegularEmployee表中的id和version列,而manager表中只包含对工作组行的引用。