开发者

How to delete interrelated objects with Hibernate

开发者 https://www.devze.com 2023-03-04 01:41 出处:网络
I have two object. Let it be company and employee. CREATE TABLE company ( company_id BIGINT(20) NOT NULL AUTO_INCREMENT,

I have two object. Let it be company and employee.

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);

And my classes look like:

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

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

Then I want to delete company with all its employees. I do it in a single transaction. I am getting smth like "java.sql.BatchUpdateException: Column 'chief_id' cannot be null"

I am able to delete only after mak开发者_如何学运维ing one of the columns nullable. For example "chief_id BIGINT(20) NULL," and then making company.chief=null before delete.

In the project we don't use Hibernate cascades and I am not able to change Database cascades.

We are using MySql 5.0.

I need smth like: disable constraints->remove entity->enable constraints. The disabled state should be accessible only within current transaction. I thought it was default behavior.


If your DBMS supports it, you can declare one of your constraints as deferrable initially deferred, so that it would be checked at the end of transaction.


You should use Hibernate cascades. Disabling/enabling database constraints is a DDL operation and it is committed immediately, there is no way to hide the "disabled state" from other transactional contexts.


If you cannot use Hibernate cascades, what you could do is use a dummy company (company_id=-1 for instance) and a dummy chief Employee object (employee_id=-1). DummyChief belongs to the company DummyCompany, and DummyCompany's chief is DummyChief.

You could then proceed in the following order:

1/ Delete all non-chief Employees in the Company.

2/ Set the Company chief employee to DummyChief (employee_id=-1)

3/ Delete the Chief employee.

4/ Delete the Company company.

0

精彩评论

暂无评论...
验证码 换一张
取 消