orphanRemoval=true does not work in bidirectional relationships (without cascading)
Description
Attachments
2
Activity
Show:

Former user January 14, 2015 at 7:25 PM
This fix caused HHH-9568. will revert this fix (HHH-9330). After reverting, covers fixing the original issue in HHH-9330.

Former user January 5, 2015 at 9:24 PM
Closing in preparation for releasing 4.2.17.

Former user November 27, 2014 at 12:24 AM
Fixed in master, 4.3, and 4.2 branches.

Ted Gulesserian November 26, 2014 at 7:32 PM
Thank you both for getting on this.
My workaround was to delete the children manually in my code, which was suboptimal.
I use GWT RequestFactory to hook into JPA.

Former user November 26, 2014 at 7:28 PM
I see that both of our tests reproduce using EntityManager. They do not reproduce using Hibernate core.
Consider the following two entities with a bidirectional relationship between them:
@Entity
@Table(name="product")
public class Product {
@Id
@GeneratedValue(strategy=GenerationType.AUTO)
private Long id;
@OneToMany(mappedBy = "product", orphanRemoval = true)//, cascade = {CascadeType.PERSIST}
private List<Feature> features = new ArrayList<Feature>();
private String name;
}
@Entity
@Table(name="feature")
public class Feature {
@Id
@GeneratedValue(strategy=GenerationType.AUTO)
private Long id;
@ManyToOne()
private Product product;
private String name;
}
Now, clearing the collection of features in the Product will not result in deleting all Features of that product, as the JPA spec requires. The workaround is setting the CascadeType.PERSIST in the Product entity.
Test Case:
entityManager.getTransaction().begin();
Product product = new Product();
List<Feature> features = new ArrayList<Feature>();
Feature newFeature = new Feature(product);
newFeature.setName("Feature 1");
entityManager.persist(newFeature);
features.add(newFeature);
product.setFeatures(features);
entityManager.persist(product);
entityManager.flush();
entityManager.getTransaction().commit();
entityManager.clear();
//1. Changing product's features
entityManager.getTransaction().begin();
Product productFound = entityManager.find(Product.class, product.getId());
log.info("found=" + productFound +" class "+productFound.getClass());
productFound.getFeatures().clear();
productFound.setName("Name changed");
Feature newFeature2 = new Feature(productFound);
newFeature2.setName("Feature 2");
//entityManager.persist(newFeature2);
//productFound.getFeatures().add(newFeature2);
log.info("Product entity is managed: " + entityManager.contains(productFound));
log.info("Updating product");
entityManager.merge(productFound);
entityManager.getTransaction().commit();