【问题标题】:Cascade delete and one-to-one mapping in hibernatehibernate中的级联删除和一对一映射
【发布时间】:2011-07-22 08:32:30
【问题描述】:

在为买家创建销售订单账单的 Web 应用程序中,我尝试创建数据库表和休眠映射。实体之间的关系是:

  1. Bill 有一个 Buyer 和一个 SaleOrder

  2. SaleOrder 有一个买家。

  3. 删除 SaleOrder 时,必须删除关联的 Bill。

我实现了java类,创建了表。

在架构中,表 SALEORDER 有一个 FK 列“BUYER_ID”。 此表没有其他外键列。 表 BILL 有两个外键,BUYER_ID 和 SALEORDER_ID。

我如何使用一对一关系 AND来映射 Bill 和 SaleOrder 以确保在删除 SaleOrder 时,Bill 也会被删除?

我很困惑,因为 由于 SaleOrder 表没有名为 INVOICE_ID 的外键,我如何在 SaleOrder.hbm.xml 中映射以下内容?

<!-- 1-to-1 modelled using n-to-n + unique  -->
    <many-to-one name="invoice" class="Invoice" column="INVOICE_ID" cascade="delete" unique="true">
    </many-to-one>

如果我只把映射放在Bill.hbm.xml中,我可以提级联删除(删除SaleOrder时应该删除Bill)?

希望有人可以提出解决方案。


我的应用程序中的类是:

class Buyer{
   private Long buyerId;
   private String name;
...
}

class SaleOrder{
    private Long saleOrderId;
    ...
    private Buyer buyer;
...
}

class Bill{
   private Long billId;
   ...
   private Buyer buyer;
   private SaleOrder saleOrder;
...
}

架构是:

CREATE TABLE BUYER(
   BUYER_ID BIGINT NOT NULL PRIMARY KEY IDENTITY,
   NAME VARCHAR(100)
);

CREATE TABLE SALEORDER(
   SALEORDER_ID BIGINT NOT NULL PRIMARY KEY IDENTITY,
   BUYER_ID BIGINT NOT NULL,
);

CREATE TABLE BILL(
  BILL_ID BIGINT NOT NULL PRIMARY KEY IDENTITY,
  BUYER_ID BIGINT NOT NULL,
  SALEORDER_ID BIGINT NOT NULL,
);
ALTER TABLE SALEORDER ADD CONSTRAINT FK_SO_BUYER FOREIGN KEY(BUYER_ID) REFERENCES BUYER(BUYER_ID);
ALTER TABLE BILL ADD CONSTRAINT FK_BILL_BUYER FOREIGN KEY(BUYER_ID) REFERENCES BUYER(BUYER_ID);
ALTER TABLE BILL ADD CONSTRAINT FK_BILL_SO FOREIGN KEY(SALEORDER_ID) REFERENCES SALEORDER(SALEORDER_ID);

【问题讨论】:

    标签: java hibernate cascade


    【解决方案1】:

    让我用注释来回答你的问题,XML 配置对我来说似乎有点过时。解决方案是在 Bill 中不保留任何引用。但是 SaleOrder 将使用关系定义上方的 CascadeType.DELETE_ORPHAN 对 Bill 和 Buyer 持有对 SaleOrder 的 1-n 引用的 1-1 引用。因此,当一个 SaleOrder 被删除时,底层的 Bill 被删除,而当一个 Buyer 被删除时,底层的 SaleOrder 和它们底层的 Bill 也被删除。

    class Bill{
        private Long billId;    
        ...    
    }
    
    class SaleOrder{    
        private Long saleOrderId;     
        ...     
        @OneToOne(cascade=CascadeType.ALL, fetch=FetchType.LAZY)
        @Cascade( {org.hibernate.annotations.CascadeType.DELETE_ORPHAN} )
        private Bill bill; 
        ... 
    }
    
    class Buyer {
        private Long buyerId;
        private String name;
        ...     
        @OneToMany(cascade=CascadeType.ALL, fetch=FetchType.LAZY)
        @Cascade( {org.hibernate.annotations.CascadeType.DELETE_ORPHAN} )
        private List<SaleOrder> saleOrders; 
        ... 
    }   
    

    您必须对您的 DAO 进行编码,以便让买方获得 SaleOrder 和 SaleOrder 获得账单。这当然是另一个问题,如何做到这一点。但是你应该在上面找到好书和网络资源。

    【讨论】:

    • 感谢您的详细回答..但是我们被要求不要将 Bill_ID 放在 SaleOrder 表或类中。这就是所有这些麻烦的原因。
    • 现在,我明白了。然后你必须“编码”,我认为你不能在 XML 中“配置”。如上所示,级联删除工作。您所要求的可能称为“对应删除”或“引用删除”,这不是 JPA 或 Hibernate 的一部分。这是使用 HQL 的代码 sn-p: Session session = (Session)entityManager.getDelegate(); // 删除引用 SaleOrder 查询的 Bill 条目 query = session.createQuery( "delete Bill where saleOrder_id = :saleOrder_id" ); query.setParameter("saleOrder_id", saleOrder_id).executeUpdate();
    猜你喜欢
    • 2013-10-21
    • 1970-01-01
    • 2015-03-24
    • 2016-05-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多