2014-10-22 3 views
1

У меня есть следующий класс. В src/groovy,Отношения между классами классов Grails с наследованием

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

классов домена BasicProfile и AcademicProfile расширить 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 (либо BasicProfile или AcademicProfile). Я пробовал 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, когда я пытаюсь запустить его. Поиск в Google говорит мне, что это проблема с классами, которые наследуются от других классов. Так что технически, если у меня нет отношения hasMany в Publication с AcademicProfile, он должен работать без проблем. Но я не хочу этого. Потому что в публикации есть много авторов (AcademicProfile s в моем случае) и автор может иметь много публикаций. Так есть способ исправить это?

ответ

1

Вы не используете наследование Hibernate - это требует, чтобы все классы были отображены. Вы просто используете обычное наследование Java/Groovy, где вы наследуете свойства и методы из базовых классов. Но Hibernate не знает об этом, поэтому он не может делать запросы по немаркированному базовому классу.

Я не уверен, почему он жалуется на AcademicProfile, но это может быть вторичная ошибка, вызванная основной проблемой.

Я считаю, что наследование Hibernate слишком сложно использовать в большинстве случаев, поэтому я использую этот подход, когда есть общий код.

Он должен работать, если вы переместили Profile в grails-app/domain. После этого вы должны переместить конфигурацию сопоставления tablePerSubclass в базовый класс и указать его только один раз.

+0

Я следил за вашими советами, и это сработало. Теперь я пытаюсь установить отношения «один» к одному «пользователь» и «базовый файл», где «пользователь» является владельцем, а другой - одним отношением b/w «AcademicProfile» и «User», где «AcademicProfile» является владелец. Я удалил 'academProfile' из' hasOne' и добавил его как поле в 'User'. Я добавил 'hasOne' в' AcademicProfile'. Но это ошибка с ошибкой: '- Ошибка поля в объекте 'org.academic.User' в поле 'academProfile': отклоненное значение [null];'. Любая идея, что не так? – aa8y

+0

Вы должны задать вопрос в отдельном вопросе –

+0

Я сделаю это. Благодаря! – aa8y

Смежные вопросы