组件作为Hibernate中的复合标识符

时间:2014-09-04 11:35:10

标签: java hibernate jpa orm composite-key

我正在关注Hibernate Documentation并尝试实施为9.4. Components as composite identifiers部分提供的示例,但面临如何实施该问题的问题。

这就是我所做的:

我的实体类:

Order.java

public class Order {
    private int id;
    private Set<OrderLine> lines = new HashSet<OrderLine>();
   // Setters & Getters
}

OrderLine.java

public class OrderLine {
    private OrderLineId id;
    private String name;
    private Order order;
   // Setters & Getters
}

OrderLineId.java

public class OrderLineId implements Serializable{
    private int lineId;
    private int orderId;
    private int customerId;
   // Setters & Getters
}

我的映射文件存在问题:

<hibernate-mapping>
   <class name="Order" table="TEST_Order">
      <id name="id" type="int" column="id">
         <generator class="native"/>
      </id>
      <set name="lines" cascade="all">
         <key column="orderId"/>
         <one-to-many class="OrderLine"/>
      </set>
   </class>

<class name="OrderLine" table="TEST_OrderLine">
    <composite-id name="id" class="OrderLineId">
        <key-property name="lineId"/>
        <key-property name="orderId"/>
        <key-property name="customerId"/>
    </composite-id>

    <property name="name"/>

    <many-to-one name="order" class="Order"
            insert="false" update="false">
        <column name="orderId"/>
        <column name="customerId"/>
    </many-to-one>
</class>
</hibernate-mapping>

当我尝试创建一个解析此映射文件的会话工厂时,我得到一个异常说:

Caused by: org.hibernate.MappingException: Foreign key (FK_89b4nqt5l2n6tfd1d5tq0ill0:TEST_OrderLine [orderId,customerId])) must have same number of columns as the referenced primary key (TEST_Order [id])
    at org.hibernate.mapping.ForeignKey.alignColumns(ForeignKey.java:110)
    at org.hibernate.mapping.ForeignKey.alignColumns(ForeignKey.java:93)
    at org.hibernate.cfg.Configuration.secondPassCompileForeignKeys(Configuration.java:1816)
    at org.hibernate.cfg.Configuration.originalSecondPassCompile(Configuration.java:1739)
    at org.hibernate.cfg.Configuration.secondPassCompile(Configuration.java:1424)
    at org.hibernate.cfg.Configuration.buildSessionFactory(Configuration.java:1844)

有人可以帮我解释如何实施文档中给出的示例。

2 个答案:

答案 0 :(得分:2)

OrderLine需要引用Order PK,它不是复合键。

这意味着多对一必须是:

<many-to-one name="order" class="Order"
        insert="false" update="false">
    <column name="orderId"/>
</many-to-one>

orderId是Order.id的FK。

然后一对多的一方将成为:

<set name="lines" cascade="all">
    <key>
        <column name="orderId"/>
    </key>
    <one-to-many class="OrderLine"/>
</set>

因此,即使OrderLine具有复合键,也会在Order.id之后进行引用,这是一个简单的键。

如果要将其他关联映射到OrderLine,例如OrderLineProduct,那么您需要使用复合键来映射父(OrderLine)和子(OrderLineProduct)之间的关联,以便OrderLineProduct具有复合外键返回OrderLine。

答案 1 :(得分:0)

在表hbm映射中你应该有相同的no。列,您正在使用什么来组合。您需要在TEST_Oder中添加这3列 示例如下:

<many-to-one name="orderLine" class="OrderLine">
<column name="lineId"/>
<column name="orderId"/>
<column name="customerId"/>
</many-to-one>

请参阅URL