【问题标题】:Hibernate parent-child mappingHibernate 父子映射
【发布时间】:2011-09-13 05:15:19
【问题描述】:

我正在尝试在 Hibernate 中映射订单及其订单项。订单项不应引用其父订单:

public class Order {
    private long id;
    private Set<OrderIter> orderItems = new HashSet<OrderItem>();

    public long id() {
        return id;
    }

    public void add(OrderItem item) {
        item.setItemNumber(orderItems.size() + 1);
        orderItems.add(item);
    }

    public Set<OrderItem> orderItems() {
        return Sets.newHashSet(orderItems);
    }
}


public class OrderItem {
    private int itemNumber;

    public int itemNumber() {
        return itemNumber;
    }

    public void setItemNumber(int itemNumber) {
        this.itemNumber = itemNumber;
    }
}

目标是让 Hibernate 在将订单项添加到订单时自动将其持久化,如下所示:

Session session = HibernateUtil.getSessionFactory().getCurrentSession();
session.beginTransaction();


Order order = (Order) session.load(Order.class, orderId);
OrderItem item = new OrderItem();
order.add(item);

// Done

session.getTransaction().commit();
HibernateUtil.getSessionFactory().close();

我查看了Chapter 24. Example: Parent/Child,但在此示例中,子项具有对父项的引用。我现在正在尝试使用Collections of dependent objects 对其进行映射:

<class name="Order" table="ORDERS">
    <id name="id" column="ORDER_ID" access="field">
        <generator class="native" />
    </id>

    <set name="orders" table="ORDER_ITEMS" access="field">
        <key column="id" />
        <composite-element class="OrderItem">
            <property name="ItemNumber" access="field" />
        </composite-element>
    </set>
</class>

这几乎可以工作,但订单 ID 和商品编号的组合应该是唯一的。如何使用 Hibernate 映射满足所有这些条件?

【问题讨论】:

  • 尝试在 Order 和 OrderItems 之间的一对多关联上使用连接表。
  • @EdSaito:使用代码item.setItemNumber(orderItems.size() + 1); 无法实现唯一性。在这里,您尝试模拟 DB 序列(或自动递增键),但是当您将新项目添加到具有相同数量项目的订单中时,这肯定会失败。只有 DB 可以以一致的方式做到这一点(想象一下两个应用程序按顺序更新项目列表的情况)。唯一简单的方法是利用自动生成的密钥,因此OrderItem 应该是一个独立的实体(请参阅@frictionlesspulley 回复)。
  • 你是对的,但这只是说明我的映射问题的一个场景。

标签: java hibernate


【解决方案1】:

这里 Order->OrderItem 之间的一对多关联是使用 JOIN TABLE 映射的。 一对多关联与唯一设置为 true 的多对多映射。 (因为一对多不知道集合上的连接表)

   <class name="Order" table="ORDERS">
        <set name="orders" table="ORDER_ORDERITEMS_RT">
            <key column="ORDER_ID" />
            <many-to-many name="OrderItem" unique="true" column="ORDERITEM_ID"/>
        </set>
    </class>

    <class name="OrderItem table="ORDERITEMS">

    </class>

以上映射满足

  1. OrderItem 没有对 Order 的引用。由于映射位于单独的表中
  2. 一对多关联使 orderid-orderitemid 对独一无二。
  3. 您可以在集合上放置适当的级联,以便在将 orderItem 添加到 Order 列表时保存它。 (图中未显示)

希望这会有所帮助。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-05-26
    • 2011-08-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-03-10
    • 1970-01-01
    相关资源
    最近更新 更多