从Hibernate 3.2.7.ga迁移到5.0.4.Final后,我在构建SessionFactory时遇到以下错误:
org.hibernate.MappingException: Foreign key (FK6ysnihr27dq6030taryppmjw3:CABLE [BOARD_1_ID])) must have same number of columns as the referenced primary key (Board [JOINT_ID,NAIL_INDEX])
at org.hibernate.mapping.ForeignKey.alignColumns(ForeignKey.java:137)
at org.hibernate.mapping.ForeignKey.alignColumns(ForeignKey.java:119)
at org.hibernate.boot.internal.InFlightMetadataCollectorImpl.secondPassCompileForeignKeys(InFlightMetadataCollectorImpl.java:1889)
at org.hibernate.boot.internal.InFlightMetadataCollectorImpl.secondPassCompileForeignKeys(InFlightMetadataCollectorImpl.java:1809)
at org.hibernate.boot.internal.InFlightMetadataCollectorImpl.processSecondPasses(InFlightMetadataCollectorImpl.java:1627)
at org.hibernate.boot.model.process.spi.MetadataBuildingProcess.complete(MetadataBuildingProcess.java:278)
at org.hibernate.boot.model.process.spi.MetadataBuildingProcess.build(MetadataBuildingProcess.java:83)
at org.hibernate.boot.internal.MetadataBuilderImpl.build(MetadataBuilderImpl.java:418)
at org.hibernate.boot.internal.MetadataBuilderImpl.build(MetadataBuilderImpl.java:87)
at org.hibernate.cfg.Configuration.buildSessionFactory(Configuration.java:692)
at org.hibernate.cfg.Configuration.buildSessionFactory(Configuration.java:724)
错误消息(JOINT_ID,NAIL_INDEX)中提到的列与Board的主键无关。 Board的主键是BOARD_ID。在Board.hbm.xml中甚至没有提到NAIL_INDEX。
Cable.hbm.xml:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "classpath:hibernate-mapping-3.0.dtd">
<hibernate-mapping package="com.oxi.beans">
<joined-subclass extends="com.oxi.beans.AbstractEntity" name="Cable" table="CABLE">
<key column="CABLE_ID"/>
<property name="tag" type="com.oxi.EscapedString"/>
<many-to-one class="Board" column="BOARD_1_ID" name="board1"/>
<many-to-one class="Board" column="BOARD_2_ID" name="board2"/>
</joined-subclass>
</hibernate-mapping>
Board.hbm.xml:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "classpath:hibernate-mapping-3.0.dtd">
<hibernate-mapping package="com.oxi.beans">
<joined-subclass extends="com.oxi.beans.AbstractEntity" name="Board">
<key column="BOARD_ID"/>
<property length="100" name="label" type="com.oxi.EscapedString"/>
<property name="unique" type="boolean"/>
<property name="standard" type="boolean"/>
<many-to-one class="Body" column="BODY_ID" name="body"/>
<many-to-one class="Joint" column="JOINT_ID" name="joint"/>
<many-to-one class="BoardInstance" column="BOARD_INSTANCE_ID" fetch="join" name="boardInstance"/>
<map name="propertyValues" table="PROPERTY_VALUE">
<key column="ENTITY_ID"/>
<map-key column="PROPERTY_ID" type="long"/>
<element column="PROPERTY_VALUE" type="com.oxi.EscapedString"/>
</map>
<many-to-one class="BoardType" column="BOARD_TYPE_ID" name="type"/>
</joined-subclass>
</hibernate-mapping>
数据库中的键定义:
ALTER TABLE CABLE ADD CONSTRAINT FK_H_F1 FOREIGN KEY (BOARD_1_ID) REFERENCES BOARD (BOARD_ID);
ALTER TABLE CABLE ADD CONSTRAINT FK_H_F2 FOREIGN KEY (BOARD_2_ID) REFERENCES BOARD (BOARD_ID);
CREATE INDEX IDX_H_F1 ON CABLE (BOARD_1_ID);
CREATE INDEX IDX_H_F2 ON CABLE (BOARD_2_ID);
在迁移到Hibernate 5之前,我使用的是configuration.setEntityResolver,以确保映射文件的dtd来自类路径。在Hibernate 5中,我没有找到指定自定义EntityResolver的方法,所以我没有使用它。这可能是为什么映射没有正确解释但错误没有给出这方面的提示的原因。