I run into the "deleted object would be re-saved by cascade" problem when I try to remove a TicketLine object from a collection that belongs to the Ticket class and TicketLine has a OneToOne association to class Reservation.
Tickets defines a collection of TicketLines with the following getter
class Tickets
...
@OneToMany(targetEntity = TicketLine.class, fetch = FetchType.EAGER)
@Fetch(org.hibernate.annotations.FetchMode.SUBSELECT)
@Cascade({org.hibernate.annotations.CascadeType.ALL,
org.hibernate.annotations.CascadeType.LOCK,
org.hibernate.annotations.CascadeType.DELETE_ORPHAN,})
public List<TicketLine> getLines() {
return ticketlines;
}
....
class Reservation defines a OneToOne relationship to TicketLines as follows:
class Reservation
...
@OneToOne()
@Cascade({org.hibernate.annotations.CascadeType.SAVE_UPDATE, org.hibernate.annotations.CascadeType.DELETE_ORPHAN})
@JoinColumn(name = "resource_id")
public TicketLine getTicketLine() {
return ticketLine;
}
Adding a TicketLine object to ticket and a Reservation object to the TicketLine object with
ticket.getLines().add(line);
session.save(ticket);
Reservation res = new Reservation();
res.setTicketLine(m_ticketline);
....
session.save(res);
works as expected. A record in Reservations is being created with the tickets id the resource_id field.
When I remove a line from the collection which has an associated Reservation object I get the following error:
Save ticket failed: org.hibernate.ObjectDeletedException: deleted object would be re-saved by cascade (remove deleted object from associations): [org.myapp.hibernate.TicketLine#ff8081814a45ebb5014a45ebe4540003]
This error only comes up when there is a Reservation associated with the line. Interestingly, a second try in a new session does not throw an exception but the reservation is not deleted!
Removing a line from the TicketLines collection can happen at many places, i.e. removing the reservation manually is not really an option. I hope this can be managed by Hibernate and I've just done something wrong with the cascade options.
Please help.
The exception has gone with the code below. However, the problem is now that line.getReservation() always returns null, although a reservation record exists.
UPDATE: adding the mappedBy attribute
in Reservation solved the last problem. line.getReservation() now also works. Sorry for bothering you.
2nd UPDATE: The previously suggested solution worked as long as the second level cache was valid. After objects had been reloaded the NPE happened again. After some poking in terminology about owning a relationship I came to the following solution that finally works.
class Tickets defines a collection of TicketLines as before.
class TicketLine defines the relationship like so:
class Reservation defines the OneToOne relationship to TicketLines as follows:
Maybe I need to explain that I've named the field resource_id so that it can also be used for additional types of one-to-one relationships in the future. But this should not play a role for now.
Adding a TicketLine object to ticket and a Reservation object to the TicketLine object now goes:
Saving the line and deleting a line with
or deleting all lines (and resarvations) for a ticket along with the ticket with
session.delete(ticket);
all works as expected.
I apologize for the many changes but this was hard to resolve for me and I wanted to provide an answer that is actually working.
Thank you.