Grails 域类与继承之间的关系



我有以下类。在src/groovy

class Profile {
    String firstName
    String middleName
    String lastName
    byte[] photo
    String bio
}

域类BasicProfileAcademicProfile扩展Profile

class BasicProfile extends Profile {
    User user
    Date dateCreated
    Date lastUpdated
    static constraints = {
        firstName blank: false
        middleName nullable: true
        lastName blank: false
        photo nullable: true, maxSize: 2 * 1024**2
        bio nullable: true, maxSize: 500
    }
    static mapping = {
        tablePerSubclass true
    }
}
class AcademicProfile extends Profile {
    User user
    String dblpId
    String scholarId
    String website
    Date dateCreated
    Date lastUpdated
    static hasMany = [publications: Publication]
    static constraints = {
        importFrom BasicProfile
        dblpId nullable: true
        scholarId nullable: true
        website nullable: true, url: true
        publications nullable: true
    }
    static mapping = { 
        tablePerSubclass true
    }
}

然后是Publication类。

class Publication {
    String dblpId
    String scholarId
    String title
    String description
    Date publicationDate
    int citations
    Date dateCreated
    Date lastUpdated
    static belongsTo = [AcademicProfile]
    static hasOne = [publisher: Publisher]
    static hasMany = [academicProfiles: AcademicProfile]
    static constraints = {
        dblpId nullable: true
        scholarId nullable: true
        title blank: false, maxSize: 100
        description nullable: true, maxSize: 500
        publicationDate: nullable: true
        academicProfiles nullable: false
    }
}

最后,我有一个User课。

class User {
    String username
    String password
    String email
    Date dateCreated
    Date lastUpdated
    static hasOne = [basicProfile: BasicProfile, academicProfile: AcademicProfile]
    static constraints = {
        username size: 3..20, unique: true, nullable: false, validator: { _username ->
            _username.toLowerCase() == _username
        }
        password size: 6..100, nullable: false, validator: { _password, user ->
            _password != user.username
        }
        email email: true, blank: false
        basicProfile nullable: true
        academicProfile nullable: true
    }
}

我的问题如下。

  1. 我想要一种关系,其中每个User都可以选择有一个Profile(BasicProfileAcademicProfile(。我尝试static hasOne = [profile: Profile]但我得到错误说Profile不同意hasOne关系。因此,我当前的设置是一种解决方法。用户不可能拥有一个Profile无论是BasicProfile还是AcademicProfile
  2. 其次,在当前设置中,我收到错误:Invocation of init method failed; nested exception is org.hibernate.MappingException: An association from the table academic_profile_publications refers to an unmapped class: org.academic.AcademicProfile尝试运行它时。谷歌搜索告诉我,这是继承自其他类的类的问题。所以从技术上讲,如果我与AcademicProfile Publication没有hasMany关系,它应该可以毫无问题地工作。但我不想这样。因为一个出版物有很多作者(在我的情况下是AcademicProfile(,而一个作者可能有很多出版物。那么有没有办法解决这个问题呢?

你没有使用Hibernate继承 - 这需要映射所有类。您只是使用常规的 Java/Groovy 继承,从基类继承属性和方法。但是Hibernate不知道这一点,所以它不能对未映射的基类进行查询。

我不确定它为什么要抱怨AcademicProfile,但它可能是由核心问题引起的次要错误。

发现在大多数情况下使用Hibernate继承太令人沮丧了,因此当有共享代码时,我使用这种方法。

如果您Profile移动到 grails-app/domain .完成此操作后,应将tablePerSubclass映射配置移动到基类,并且仅指定一次。

最新更新