2011-05-10 52 views
1

我有兩個對象。讓它成爲公司和員工。如何用Hibernate刪除相互關聯的對象

CREATE TABLE company (
    company_id BIGINT(20) NOT NULL AUTO_INCREMENT, 
    name VARCHAR(255) NOT NULL, 
    chief_id BIGINT(20) NOT NULL, 
    PRIMARY KEY (company_id), 
    CONSTRAINT fk_company_chief 
    FOREIGN KEY (chief_id) 
    REFERENCES employee (employee_id) 
    ON DELETE NO ACTION 
    ON UPDATE NO ACTION); 

CREATE TABLE employee(
    employee_id BIGINT(20) NOT NULL AUTO_INCREMENT, 
    name VARCHAR(255) NOT NULL, 
    company_id BIGINT(20) NOT NULL, 
    PRIMARY KEY (employee_id), 
    CONSTRAINT fk_employee_company 
    FOREIGN KEY (chief_id) 
    REFERENCES employee (company_id) 
    ON DELETE NO ACTION 
    ON UPDATE NO ACTION); 

而且我的課是這樣的:

class Employee { 
    long id; 
    String name; 
    Company company; 
} 

class Company{ 
    long id; 
    String name; 
    Employee chief; 
} 

然後我想刪除公司所有員工。我在一次交易中完成。我越來越像"java.sql.BatchUpdateException: Column 'chief_id' cannot be null"

我能夠刪除後,使其中一列可以爲空。例如「chief_id BIGINT(20)NULL」,然後在刪除前使company.chief = null。

在項目中,我們不使用Hibernate級聯,我無法更改數據庫級聯。

我們使用的是MySql 5.0。

我需要smth像:禁用約束 - >刪除實體 - >啓用約束。禁用狀態只能在當前事務中訪問。我認爲這是默認行爲。

+0

你沒有在這裏指定JPA註釋,我希望它的1 .. *(公司 - 員工)關係是什麼,你可以添加nullable = true在POJO中通過ID定義的註釋,是否有意義? – Narayan 2011-05-10 16:05:02

回答

0

您應該使用Hibernate級聯。禁用/啓用數據庫約束是DDL操作並立即提交,無法將「禁用狀態」與其他事務性上下文隱藏起來。

1

如果你的數據庫管理系統支持它,你可以聲明你的一個約束條件爲deferrable initially deferred,以便在事務結束時檢查它。

+0

我喜歡你的解決方案!但是我們使用的是Mysql 5.0,我無法使用它。謝謝! – Zalivaka 2011-05-11 07:33:01

+0

我想知道如果MySql立即執行檢查,這個相關數據是如何保存的? – Zalivaka 2011-05-11 07:46:35

0

如果您不能使用Hibernate級聯,您可以做的是使用虛擬公司(例如company_id = -1)和虛擬主要Employee對象(employee_id = -1)。 DummyChief屬於DummyCompany公司,DummyCompany的負責人是DummyChief。

然後,您可以進行以下順序:

1 /刪除所有非首席員工在公司。

2 /設定公司首席員工DummyChief(EMPLOYEE_ID = -1)

3 /刪除行政僱員。

4 /刪除公司公司。

相關問題