OneToMany - org.hibernate.AnnotationException: mappedBy ссылается на неизвестное целевое свойство объекта

Я пытаюсь сгенерировать схему БД из классов моего домена, используя hibernate-tools.jar, входящий в комплект OpenXava.

К сожалению, два занятия с ассоциацией OneToMany доставляют мне неприятности.

Это первое:

@Entity
public class Deceased extends ObjectWithId {

    //stuff

    @OneToMany(mappedBy = "deceased", fetch = FetchType.EAGER, cascade = CascadeType.ALL, orphanRemoval = true)
    @Access(AccessType.PROPERTY)
    public Set<DeceasedTransferDossier> getDeceasedTransferDossier() {
        return deceasedTransferDossier;
    }

    public void setDeceasedTransferDossier(
            Set<DeceasedTransferDossier> transferDossiers) {
        this.deceasedTransferDossier = transferDossiers;
    }

    //other stuff
}

Это другой:

@Entity
public class DeceasedTransferDossier extends DeceasedDossier {

    //stuff

    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "deceased_fk")
    @Override
    public Deceased getDeceased() {
        return deceased;
    }

    @Override
    public void setDeceased(Deceased deceased) {
        this.deceased = deceased;
    }

    //other stuff
}

Это исключение, которое возникает:

[hibernatetool] An exception occurred while running exporter #2:hbm2ddl (Generates database schema)
[hibernatetool] To get the full stack trace run ant with -verbose
[hibernatetool] org.hibernate.AnnotationException: mappedBy reference an unknown target entity property: com.infoone.siglo.entity.DeceasedTransferDossier.deceased in com.infoone.siglo.entity.Deceased.deceasedTransferDossier
      [ant] Exiting C:\Users\AlejandroEduardo\Documents\workspace-sts-3.1.0.RELEASE-2\OpenXava\build.xml.

BUILD FAILED
C:\Users\AlejandroEduardo\Documents\workspace-sts-3.1.0.RELEASE-2\SigloXava\build.xml:46: The following error occurred while executing this line:
C:\Users\AlejandroEduardo\Documents\workspace-sts-3.1.0.RELEASE-2\OpenXava\build.xml:1016: org.hibernate.AnnotationException: mappedBy reference an unknown target entity property: com.infoone.siglo.entity.DeceasedTransferDossier.deceased in com.infoone.siglo.entity.Deceased.deceasedTransferDossier
    at org.apache.tools.ant.ProjectHelper.addLocationToBuildException(ProjectHelper.java:551)
    at org.apache.tools.ant.taskdefs.Ant.execute(Ant.java:444)
    at org.apache.tools.ant.UnknownElement.execute(UnknownElement.java:291)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:601)
    at org.apache.tools.ant.dispatch.DispatchUtils.execute(DispatchUtils.java:106)
    at org.apache.tools.ant.Task.perform(Task.java:348)
    at org.apache.tools.ant.Target.execute(Target.java:392)
    at org.apache.tools.ant.Target.performTasks(Target.java:413)
    at org.apache.tools.ant.Project.executeSortedTargets(Project.java:1399)
    at org.apache.tools.ant.Project.executeTarget(Project.java:1368)
    at org.apache.tools.ant.helper.DefaultExecutor.executeTargets(DefaultExecutor.java:41)
    at org.eclipse.ant.internal.launching.remote.EclipseDefaultExecutor.executeTargets(EclipseDefaultExecutor.java:32)
    at org.apache.tools.ant.Project.executeTargets(Project.java:1251)
    at org.eclipse.ant.internal.launching.remote.InternalAntRunner.run(InternalAntRunner.java:424)
    at org.eclipse.ant.internal.launching.remote.InternalAntRunner.main(InternalAntRunner.java:138)
Caused by: C:\Users\AlejandroEduardo\Documents\workspace-sts-3.1.0.RELEASE-2\OpenXava\build.xml:1016: org.hibernate.AnnotationException: mappedBy reference an unknown target entity property: com.infoone.siglo.entity.DeceasedTransferDossier.deceased in com.infoone.siglo.entity.Deceased.deceasedTransferDossier
    at org.hibernate.tool.ant.HibernateToolTask.reportException(HibernateToolTask.java:226)
    at org.hibernate.tool.ant.HibernateToolTask.execute(HibernateToolTask.java:189)
    at org.apache.tools.ant.UnknownElement.execute(UnknownElement.java:291)
    at sun.reflect.GeneratedMethodAccessor5.invoke(Unknown Source)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:601)
    at org.apache.tools.ant.dispatch.DispatchUtils.execute(DispatchUtils.java:106)
    at org.apache.tools.ant.Task.perform(Task.java:348)
    at org.apache.tools.ant.Target.execute(Target.java:392)
    at org.apache.tools.ant.Target.performTasks(Target.java:413)
    at org.apache.tools.ant.Project.executeSortedTargets(Project.java:1399)
    at org.apache.tools.ant.helper.SingleCheckExecutor.executeTargets(SingleCheckExecutor.java:38)
    at org.eclipse.ant.internal.launching.remote.EclipseSingleCheckExecutor.executeTargets(EclipseSingleCheckExecutor.java:30)
    at org.apache.tools.ant.Project.executeTargets(Project.java:1251)
    at org.apache.tools.ant.taskdefs.Ant.execute(Ant.java:442)
    ... 16 more
Caused by: org.hibernate.AnnotationException: mappedBy reference an unknown target entity property: com.infoone.siglo.entity.DeceasedTransferDossier.deceased in com.infoone.siglo.entity.Deceased.deceasedTransferDossier
    at org.hibernate.cfg.annotations.CollectionBinder.bindStarToManySecondPass(CollectionBinder.java:666)
    at org.hibernate.cfg.annotations.CollectionBinder$1.secondPass(CollectionBinder.java:626)
    at org.hibernate.cfg.CollectionSecondPass.doSecondPass(CollectionSecondPass.java:66)
    at org.hibernate.cfg.Configuration.originalSecondPassCompile(Configuration.java:1586)
    at org.hibernate.cfg.Configuration.secondPassCompile(Configuration.java:1359)
    at org.hibernate.cfg.Configuration.buildMappings(Configuration.java:1300)
    at org.hibernate.tool.ant.ConfigurationTask.getConfiguration(ConfigurationTask.java:56)
    at org.hibernate.tool.ant.HibernateToolTask.getConfiguration(HibernateToolTask.java:302)
    at org.hibernate.tool.ant.Hbm2DDLExporterTask.createExporter(Hbm2DDLExporterTask.java:51)
    at org.hibernate.tool.ant.ExporterTask.execute(ExporterTask.java:39)
    at org.hibernate.tool.ant.HibernateToolTask.execute(HibernateToolTask.java:186)
    ... 29 more

Позвольте мне указать на некоторые возможные источники вреда:

  1. Класс DeceasedTransferDossier расширяет DeceasedDossier, который уже имеет неабстрактный метод доступа getDeceased();
  2. Все сущности имеют общий родительский класс с именем Identifiable:

    @MappedSuperclass
    public class Identifiable {
    
        private String id;
    
        public void setId(String id) {
            this.id = id;
        }
        @Id @GeneratedValue(generator="system-uuid") @Hidden 
        @GenericGenerator(name="system-uuid", strategy = "uuid")
        @Column(length=32)
        public String getId() {
            return id;
        }
    }
    

Позвольте мне отметить, что такая структура уже работает в контейнере Spring-data + Hibernate, где схема БД успешно создается (Spring-data 3.1.2 + Hibernate 4.1.6). OpenXava объединяет более старую версию Hibernate и Hibernate Tools, поэтому я попытался настроить его вручную, обновив его до:

  • Hibernate Tools 4.0.0.CR1 (самая последняя версия, которую я смог найти в репозитории Maven);
  • Hibernate 4.0.0.Final (зависит от версии Hibernate Tools 4.0.0.CR1);
  • и обновление всех необходимых зависимостей от каскада.

Я надеялся, что такое обновление может решить мою проблему, но, к сожалению, исключение org.hibernate.AnnotationException осталось прежним.

1 ответ

Проблема заключается в том, что вы расширяете DeceasedDossier и существенно меняете (или определяете?) Отношения между классом-потомком (DeceasedTransferDossier) и Deceased.

Мы не знаем, как выглядит предок (DeceasedDossier), но это может быть несколько вещей. Либо вы не аннотируете этот класс, и поэтому вы сталкиваетесь с проблемами, когда поставщик постоянства пытается "выяснить", что означает покойный для DeceasedTransferDossier. Или вы аннотируете это неправильно. Я думаю, что может быть и другая проблема, но снова нам нужно будет увидеть DeceasedDossier.

Итак, решение, не зная, что происходит с DeceasedDossier:

  1. Если вы не аннотируете класс DecreasedDossier, просто сообщите провайдеру, что вы используете PROPERTY-доступ для покойного, в DeceasedTransferDossier.

    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "deceased_fk")
    @Override
    @Access(AccessType.PROPERTY)
    public Deceased getDeceased() {
        return deceased;
    }
    
  2. Если вы аннотируете DeceasedDossier, то нам нужно увидеть проблему, чтобы разобраться с этим. Но, держу пари, просто добавив аннотацию @Access на умершем получателе DeceasedTransferDossier, вы обнаружите корневую проблему в этом случае (когда провайдер пытается "выяснить", что происходит с DeceasedDossier.

Наконец, я должен сказать, что это похоже на странные отношения здесь. Я полагаю, что DeceasedDossier имеет состояние Смерть (переменная экземпляра), так как вы упоминаете "неабстрактный получатель", но вы также определяете такие отношения в потомке. Поскольку ваш вопрос не об этом, я не буду "критиковать", но, возможно, рассмотрим, почему вы разделили это как таковое.

Другие вопросы по тегам