Remove Order in hibernate

Viewed 926

I have 4 entities:

Profile which has a relation with companyContract:

@OneToMany(fetch = FetchType.EAGER, mappedBy = "profile", cascade = { CascadeType.ALL })
@Fetch(value = FetchMode.SUBSELECT)
@Cascade({ org.hibernate.annotations.CascadeType.SAVE_UPDATE, org.hibernate.annotations.CascadeType.DELETE_ORPHAN })
private List<CompanyContract> companyContracts;

CompanyContract which has a relation with timesheet:

@OneToMany(mappedBy = "companyContract", cascade = { CascadeType.ALL },orphanRemoval = true, fetch = FetchType.EAGER)
@Fetch(FetchMode.SUBSELECT)
@Cascade({ org.hibernate.annotations.CascadeType.SAVE_UPDATE, org.hibernate.annotations.CascadeType.DELETE_ORPHAN })
private List<Timesheet> timesheets;

    @ManyToOne
@JoinColumn(name = "IDPROFILE")
private Profile profile;

Timesheet which has a relation with invoice:

@OneToMany(mappedBy = "timesheet", cascade = CascadeType.ALL, fetch = FetchType.EAGER)
@Fetch(value = FetchMode.SUBSELECT)
@Cascade({ org.hibernate.annotations.CascadeType.SAVE_UPDATE, org.hibernate.annotations.CascadeType.DELETE_ORPHAN })
private List<Invoice> invoices;

@ManyToOne
@JoinColumn(name = "IDCONTRACT")
private CompanyContract companyContract;

Invoice:

@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "ID_TIMESHEET")
private Timesheet timesheet;

So As you can see here, I'm using org.hibernate.annotations.CascadeType.DELETE_ORPHAN so I can delete the children of a parent.

If I execute this:

Profile p = companyContract.getProfile();
p.getCompanyContracts().remove(companyContract);
companyContract.setProfile(null);
profileService.update(p);

---> The order of removal should be:

Remove invoices --> Timesheets --> CompanyContract, No ?

And instead I'm getting this error:

org.hibernate.exception.ConstraintViolationException: Column 'IDCONTRACT' cannot be null

And I've checked, this error happens after profileService.updateProfile(p);

2 Answers

The problem seems to be that the column IDCONTRACTin the table that holds Timesheets has a NOT NULL restriction. Remove it and try again.

If you're autogenerating the schema, try adding @Basic(optional = true) to Timesheet.companyContract:

@Basic(optional = true)
@ManyToOne
@JoinColumn(name = "IDCONTRACT")
private CompanyContract companyContract;

This is working completely fine. I see all associated child entities getting successfully deleted.

Check the below code.

Use orphanRemoval = true like below instead of deprecated way org.hibernate.annotations.CascadeType.DELETE_ORPHAN , which you are using.

@OneToMany(mappedBy = "companyContract", cascade = { CascadeType.ALL },orphanRemoval = true, fetch = FetchType.EAGER)

Find code below

public void check() {

    System.out.println("Start check() in DummyDAOImpl");
    Session session = sessionFactory.openSession();

    CompanyContract companyContract = session.get(CompanyContract.class, 2);
    Profile p = companyContract.getProfile();
    p.getCompanyContracts().remove(companyContract);
    companyContract.setProfile(null);
    session.update(p);

    session.flush();
    session.close();

    System.out.println("Executed check() in DummyDAOImpl");

}
Related