Reputation: 139
Where are a lot of similar topics but i still can't handle it myself, sorry.
So, i have object "Bank" which is a parent of an "Office".
I am trying to delete single Office, but then i do it, all offices of parent bank are being deleted.
Here's the code:
Bank
@Entity
@Table(name = "BANKS")
public class Bank {
public Bank() {
}
public Bank(String name) {
this.name = name;
}
@Id
@Column(name = "ID")
@GeneratedValue
private int id;
@Column(name = "name")
private String name;
@OneToMany(mappedBy = "bank", cascade = CascadeType.ALL, fetch = FetchType.EAGER, orphanRemoval = true)
@JoinColumn(name = "BANK_ID")
private List<Office> officeList;
Office
@Entity
@Table(name = "OFFICES")
public class Office {
public Office() {
}
public Office(String city, String address, String workingHours, Bank bank) {
this.city = city;
this.address = address;
this.workingHours = workingHours;
this.bank = bank;
}
@Id
@Column(name = "ID")
@GeneratedValue
private int id;
@ManyToOne(fetch = FetchType.EAGER, cascade = CascadeType.REMOVE)
@JoinColumn(name = "BANK_ID")
private Bank bank;
@Column(name = "CITY")
private String city;
@Column(name = "ADDRESS")
private String address;
@Column(name = "WORKING_HOURS")
private String workingHours;
And OfficeDAO
@Repository
@Transactional
public class OfficeDAOImpl implements OfficeDAO {
@Autowired
private SessionFactory sessionFactory;
@Override
public Office getByOffice_ID(int Office_ID) {
return (Office) sessionFactory.getCurrentSession().get(Office.class, Office_ID);
}
@Override
public List<Office> getAllOffice() {
Criteria criteria = sessionFactory.getCurrentSession().createCriteria(Office.class);
return criteria.list();
}
@Override
public int save(Office Office) {
return (Integer) sessionFactory.getCurrentSession().save(Office);
}
@Override
public void update(Office Office) {
sessionFactory.getCurrentSession().merge(Office);
}
@Override
public void view(Office Office) {
sessionFactory.getCurrentSession().merge(Office);
}
@Override
public void delete(int Office_ID) {
Office s = getByOffice_ID(Office_ID);
System.out.println("trying to delete" + Office_ID);
sessionFactory.getCurrentSession().delete(s);
}
}
Hibernate query trace then deleting only office:
Hibernate: delete from offices where id=?
Hibernate: delete from offices where id=?
Hibernate: delete from offices where id=?
Hibernate: delete from offices where id=?
Hibernate: delete from offices where id=?
Hibernate: delete from offices where id=?
Hibernate: delete from offices where id=?
Hibernate: delete from offices where id=?
Hibernate: delete from offices where id=?
Hibernate: delete from offices where id=?
Hibernate: delete from offices where id=?
Hibernate: delete from offices where id=?
Hibernate: delete from offices where id=?
Hibernate: delete from offices where id=?
Hibernate: delete from offices where id=?
Hibernate: delete from offices where id=?
Hibernate: delete from offices where id=?
Hibernate: delete from offices where id=?
Hibernate: delete from banks where id=?
What am i doing wrong? Any advice will be much appreciated.
UPDATE
If i delete cascade = CascadeType.REMOVE from office, hibernate won't send any delete request.
Upvotes: 3
Views: 6631
Reputation: 19956
An explanation why we have such behavior.
Bank
is a parent of the officeList
, so that makes sense to delete officeList
if we delete Bank
.
@ManyToOne(fetch = FetchType.EAGER, cascade = CascadeType.REMOVE)
@JoinColumn(name = "BANK_ID")
private Bank bank;
This annotation means that Office
is a parent of Bank
too
So if we delete Office
-> we should delete Bank
-> we should delete all offices of the Bank
and the Bank
itself.
We see it in the logs
Hibernate: delete from offices where id=?
Hibernate: delete from offices where id=?
Hibernate: delete from banks where id=?
Also we can't use @JoinColumn
here, if we have mappedBy
(with Hibernate 5).
@OneToMany(mappedBy = "bank", cascade = CascadeType.ALL, fetch = FetchType.EAGER, orphanRemoval = true)
@JoinColumn(name = "BANK_ID")
private List<Office> officeList;
Upvotes: 0
Reputation: 139
I've found the issue. It looks like hibernate can't remove child entity while it is in parent list, so just add this to delete method in office:
s.getBank().getOfficeList().remove(s);
And yeah, Cascade.Remove at office should not exist.
Upvotes: 1
Reputation: 1856
You should to configure CascadeType
in wright way...
All
- is not the best choice in your case. Try DETACH
or REMOVE
. It should help :)
More about CascadeType can be found here.
Upvotes: 1