Ilya
Ilya

Reputation: 29703

Remove entity with relationships

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

Answers (2)

Hui Zheng
Hui Zheng

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

gaborsch
gaborsch

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

Related Questions