Reputation: 29703
I have next entities. Car
has ManyToMany relationship with Human
. I am using auxiliary class Assign between Car and User
@Entity
public class Car implements Serializable
{
//...
@LazyCollection(LazyCollectionOption.TRUE)
@OneToMany(cascade = CascadeType.ALL, mappedBy = "car")
private Set<Assign> cars = new HashSet<Assign>();
//...
}
@Entity
class Assign implements Serializable
{
//...
@LazyCollection(LazyCollectionOption.FALSE)
@ManyToOne
@JoinColumn(name = "HUMAN_CAR", nullable = false)
private Human human;
@LazyCollection(LazyCollectionOption.FALSE)
@ManyToOne
@JoinColumn(name = "CAR_HUMAN", nullable = false)
private Car car;
//..
}
@Entity
public class Human implements Serializable
{
//...
@LazyCollection(LazyCollectionOption.TRUE)
@OneToMany(cascade = CascadeType.ALL, mappedBy = "human")
private Set<Assign> cars = new HashSet<Assign>();
// ...
}
Now I try to remove car inside container managed transaction
public void deleteCar(final long id)
{
final Car car = entityManager.find(roleId, Car.class);
entityManager.remove(car);
}
but I get
Caused by: javax.persistence.EntityNotFoundException: deleted entity passed to persist: [com.dto.Assign#<null>]
Upvotes: 1
Views: 138
Reputation: 10222
Before remove car
, you need first remove car
from Assign
.
There is another design problem here. You have CascadeType.ALL
on cars
in Car
entity, which means Car and its assigns has a composition relationship(not simply aggregation/association relationship). On the other hand, same relationship exists between Human and its assigns. Obviously assigned cars
could be shared between a car and a human, but composition relationship follows non-shared semantics. Suppose one deletes a car and cascade delete its assigns, those shared in person
side will become orphans.
Upvotes: 1
Reputation: 15758
Remove the Assign
-s before you remove the Car
public void deleteCar(final long id)
{
final Car car = entityManager.find(roleId, Car.class);
for(Assign assign : car.getAssigns()) {
entityManager.remove(assign);
}
entityManager.remove(car);
}
Your getter may be differently named, I can't see that code.
Upvotes: 1