Cascade delete and one-to-one mapping in hibernate
In a web application which creates Bill for SaleOrder for a Buyer, I tried to create database tables and hibernate mappings. The relationships between the entities are:
A Bill has a Buyer and a SaleOrder
A SaleOrder has a Buyer.
When a SaleOrder is deleted, the associated Bill must be deleted.
I Implemented the java classes,created tables.
In the schema, table SALEORDER has a FK column 'BUYER_ID'. This table has no other foreign key columns. The table BILL has two foreign keys, BUYER_ID and SALEORDER_ID.
How do I map Bill and SaleOrder using one-to-one relation AND make sure that when a SaleOrder is deleted, the Bill is also delet开发者_如何学编程ed?
I am confused because, since the SaleOrder table has no foreign key named INVOICE_ID, how can I map the following in 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>
If I put the mapping only in Bill.hbm.xml,will I be able to mention cascade delete (which should delete Bill when SaleOrder is deleted)?
Hope someone can suggest a solution.
The classes in my application are:
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;
...
}
The schema is:
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);
Let me answer your questions using annotations, the XML configuration seems a little old-fashioned to me. The solution is to hold no references in Bill. But SaleOrder will hold a 1-1 reference to Bill and Buyer a 1-n reference to SaleOrder, using CascadeType.DELETE_ORPHAN above the relationship definitions. Thus, when a SaleOrder is deleted, the underlying Bill is deleted, and when a Buyer is deleted the underlying SaleOrder's and them underlying Bill's are deleted.
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;
...
}
You must code your DAOs to get the Buyer for a SaleOrder and the SaleOrder for a bill. This is of course, another question, how to do this. But you should find good books and web resources on it.
精彩评论