0

我正在尝试使用 OpenXava 中捆绑的 hibernate-tools.jar 从我的域类生成数据库模式。

不幸的是,两个具有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扩展了已具有非抽象getDeceased()访问器的DeceasedDossier
  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 容器中工作,其中成功创建了 DB 模式(Spring-data 3.1.2 + Hibernate 4.1.6)OpenXava 捆绑了旧版本的 Hibernate 和 Hibernate 工具,因此我尝试手动调整它,将其更新为:

  • Hibernate Tools 4.0.0.CR1(我可以在 Maven 存储库中找到的最新版本);
  • Hibernate 4.0.0.Final(Hibernate Tools 4.0.0.CR1 依赖的版本);
  • 并更新所有必要的级联依赖。

我希望这样的更新可以解决我的问题,但不幸的是,org.hibernate.AnnotationException 保持不变。

4

1 回答 1

2

The problem lies with the fact that you are extending DeceasedDossier and essentially changing (or defining?) the relationship between the descedent class (DeceasedTransferDossier) and Deceased.

We do not know what the ancestor (DeceasedDossier) looks like, but it could be a few things. Either you are not annotating this class and so you are running into issues when the persistence provider tries to "figure out" what deceased means to DeceasedTransferDossier. Or, you are annotating it incorrectly. I guess there could also be another issue, but again we would need to see DeceasedDossier.

So, solution without really knowing what is going on with DeceasedDossier:

  1. If you are not annotating the DecreasedDossier class, then just tell the provider you are using PROPERTY access for deceased, on DeceasedTransferDossier.

    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "deceased_fk")
    @Override
    @Access(AccessType.PROPERTY)
    public Deceased getDeceased() {
        return deceased;
    }
    
  2. If you ARE annotating DeceasedDossier, then we need to see the problem to figure it out. But, I bet you by just adding the @Access annotation on DeceasedTransferDossier's deceased getter, you will expose the root problem in this case (when the provider tries to "figure out" what is going on with DeceasedDossier.

Finally, I have to say that this seems like an odd relationship here. I imagine DeceasedDossier has Deceased state (an instance variable) since you mention the "non-abstract getter", but you are also defining such a relationship in the descendent. Since your question isn't about this, I won't "critique", but maybe review why you have split it up as such.

于 2013-06-15T18:23:47.483 回答