首页 > 解决方案 > Hibernate 5 和 HBM 映射问题,Schema-validation: missing table

问题描述

我正在使用现有的 Java 应用程序并致力于从 Hibernate 3 更新它,我们在其中使用 hbm.xml 文件进行实体映射。我们现在使用的是 Hibernate 5.5.5.Final,并且代码使用 ehcache 编译,但是现在开始运行代码时出现错误。

我应该从 Hibernate 属性之一开始:验证

我现在收到的错误消息是:

org.hibernate.tool.schema.spi.SchemaManagementException: Schema-validation: missing table [my_db_dev.Project_myTemplateInfos]
at org.hibernate.tool.schema.internal.AbstractSchemaValidator.validateTable(AbstractSchemaValidator.java:121)
at org.hibernate.tool.schema.internal.GroupedSchemaValidatorImpl.validateTables(GroupedSchemaValidatorImpl.java:42)
at org.hibernate.tool.schema.internal.AbstractSchemaValidator.performValidation(AbstractSchemaValidator.java:89)
at org.hibernate.tool.schema.internal.AbstractSchemaValidator.doValidation(AbstractSchemaValidator.java:68)
at org.hibernate.tool.schema.spi.SchemaManagementToolCoordinator.performDatabaseAction(SchemaManagementToolCoordinator.java:200)
at org.hibernate.tool.schema.spi.SchemaManagementToolCoordinator.process(SchemaManagementToolCoordinator.java:81)
at org.hibernate.internal.SessionFactoryImpl.<init>(SessionFactoryImpl.java:327)
at org.hibernate.boot.internal.SessionFactoryBuilderImpl.build(SessionFactoryBuilderImpl.java:471)

我很想完全删除所有 hbm.xml 文件并用带有注释的实体映射 POJO 替换它们,但是,现在这不是一个选项。现有的应用程序有这个贯穿始终的不同对象模型,所以我现在不想弄乱它。那将在下一阶段。

根据错误,我缺少一个名为“Project_myTemplateInfos”的表,并且没有具有此名称的表。相反,有一个名为“Project”的表,其 hbm.xml 文件如下所示。

<hibernate-mapping package="com.myApp.server.model">
    <class name="Project" table="project" dynamic-update="true">
        <id name="id" column="id">
            <generator class="native" />
        </id>
     <property name="name" not-null="true"/>
     <property name="displayCity" not-null="true"/>
     
     <list name="myTemplateInfos" cascade="all, delete-orphan" lazy="false" >
        <key column="projectId" not-null="false" />
        <list-index column="listIndex" />
            <composite-element class="com.myApp.server.model.MyTemplateInfo" >
                <property name="name"        not-null="false" />
                <property name="frequency"   not-null="false" />
            </composite-element>
       </list>

    </class>
</hibernate-mapping>

如您所见,“myTemplateInfos”是项目表中的一个列表。创建 POJO 后,它看起来像这样。

@ModelBean(IProject.class)
@PermissionIdentifier("project")
public class Project extends ModelObject implements Serializable, IProject {

    private Long id;
    private String displayCity = "";
    private List<IMyTemplateInfo> myTemplateInfos = Lists.newArrayList();
    // getters and setters
    // hashcode and equals
}

接下来,我们在数据库中确实有另一个名为“myTemplateInfos”的表,并且我们确实有一个用于该表的 hbm xml 文件,如下所示......实际上我们没有用于此的 hbm xml 文件,所以也许这就是问题所在。我将为此创建一个 hbm xml 文件,看看是否能解决问题。

不过,我们确实有这个对象“MyTemplateInfo”的 POJO。

如果我只是从 hbm 映射和 Project 对象中删除他的 List,问题当然会消失,但是 hbm.xml 文件中有另一个 Set 会给我同样的问题,但是缺少一个新的表。

问题变成了如何修复此错误消息。是'Project'的hbm xml文件中的问题,还是Project POJO中的问题,或者'MyTemplateInfo'的hbm文件不存在的事实?

标签: javaxmlhibernate

解决方案


解决方案是修复 hbm xml 映射。因为我已经有 15 年没有这样做了,所以我对它很生疏。我无法告诉你我当时有多高兴切换到 Java POJO 用于带有注释的 Hibernate Entity 类。但现在,不幸的是,我又不得不再次处理这些 xml 文件。

我有“mycommunitytemplateinfos”的表我为它创建了一个新的 hbm xml 文件,如下所示,并将其放在 hibernate.cfg.xml 文件中,然后再进行其他 hbm xml 映射。

<hibernate-mapping package="com.myapp.server.model">
    <class name="MyTemplateInfo" table="mytemplateinfos">
        <id name="id" column="projectId">
            <generator class="native"/>
        </id>
        <property name="name"        not-null="false" />
        <property name="frequency"   not-null="false" />
    </class>
</hibernate-mapping>

这个和实际类之间的映射很好,因为我已经测试过了。我将 hbm 文件放在了 hibernate.cfg.xml 文件中,放在 Project.hbm.xml 文件之前,并使用一对多标签修改了 Project.hbm.xml,如下所示:

<list name="myTemplateInfos" cascade="all, delete-orphan" lazy="false" >
    <key column="projectId" not-null="false" />
    <list-index column="listIndex" />
    <one-to-many class="com.myApp.server.model.MyTemplateInfo" />
</list>

这似乎奏效了。我不得不做几次这样的事情,直到我得到正确的映射。在这个时代,关于 hbm xml 文件的信息并不多。Hibernate 5 确实使用了这些,但我知道首选方式是带注释的 Java POJO。不幸的是,我陷入了一种我还不能做到这一点的境地。


推荐阅读