【问题标题】:Components as composite identifiers in Hibernate组件作为 Hibernate 中的复合标识符
【发布时间】:2014-10-29 03:25:13
【问题描述】:

我正在关注 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)

有人可以帮助我如何实现文档中给出的示例。

【问题讨论】:

    标签: java hibernate jpa orm composite-key


    【解决方案1】:

    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。

    【讨论】:

    • 嗨弗拉德,非常感谢您的回复。我根据您的建议对我的 hbm 文件进行了更改,但仍然遇到相同的异常。
    • 检查我更新的答案。我被那个复合键弄糊涂了,但是一对多的OrderLine 关联只需要一个简单的键(Order.id)。
    • 按照您的回答解决了我的问题。根据您的解释,我现在很清楚这个问题,所以我尝试使用我的问题中提到的相同映射文件,并为我的 Order 实体创建了一个复合 ID,即使现在也没有问题。非常感谢弗拉德。
    【解决方案2】:

    在两个表 hbm 映射中,您应该有相同的编号。列,您用于制作复合材料的内容。您需要在 TEST_Oder 中添加这 3 列。
    示例:

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

    引用相同的URL

    【讨论】:

    • 现在我开始收到异常Caused by: org.hibernate.MappingException: Foreign key (FK_d3m49ikqc9585v3uro8r58a8q:TEST_OrderLine [lineId,orderId,customerId])) must have same number of columns as the referenced primary key (TEST_Order [id])
    • @Chaitanya 它只是列映射的问题,你需要更多地解决它,因为它是一种配置问题。
    • 是的,这就是我无法弄清楚并在 SO 中寻求帮助的原因
    猜你喜欢
    • 2013-11-15
    • 2012-08-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-12-06
    • 1970-01-01
    • 2022-11-30
    • 1970-01-01
    相关资源
    最近更新 更多