Zalivaka
Zalivaka

Reputation: 763

How to delete interrelated objects with Hibernate

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 making 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.

Upvotes: 1

Views: 575

Answers (3)

TBW
TBW

Reputation: 138

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.

Upvotes: 0

axtavt
axtavt

Reputation: 242686

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.

Upvotes: 1

Olaf
Olaf

Reputation: 6289

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.

Upvotes: 0

Related Questions