JPA delete all entites works strange

2019-07-23 04:16发布

问题:

I have an entityrelation like this:

In the ParentObj class:

@OneToMany(mappedBy = "parentObj", fetch = FetchType.EAGER, cascade = CascadeType.ALL, orphanRemoval = true)
private List<ChildObj> list;

In the ChildObj class:

@JoinColumn(name="PARENT_OBJ")
@ManyToOne
private ParentObj parentObj;

When the parent object persisted or removed, the child is persisted/removed as well. BUT when I try to remove all the entities with a CriteriaDelete like:

CriteriaDelete<ParentObj> query = builder.createCriteriaDelete(ParentObj.class);
            query.from(ParentObj.class);
            em.createQuery(query).executeUpdate();

or a simple query like this:

em.createQuery("DELETE FROM ParentObj po").executeUpdate();

I got a ConstraintViolationException, could somebody explain why this is happening?

I'm using org.hibernate.ejb.HibernatePersistence provider with JTA on a Wildfly server.

回答1:

The following

em.createQuery("DELETE FROM ParentObj po").executeUpdate(); 

is a JPQL bulk update command and as the JPQL language reference notes:

10.2.9. JPQL Bulk Update and Delete

Operations Bulk update and delete operations apply to entities of a single entity class (together with its subclasses, if any).

A delete operation only applies to entities of the specified class and its subclasses. It does not cascade to related entities.....

https://docs.oracle.com/html/E24396_01/ejb3_langref.html#ejb3_langref_bulk_ops

So essentially you are attempting to remove an entity which, due to lack of cascading, will still have FK references in the database. Hence the exception.

CriteriaDelete has similar limitations:

https://docs.oracle.com/javaee/7/api/javax/persistence/criteria/CriteriaDelete.html

Criteria API bulk delete operations map directly to database delete operations. The persistence context is not synchronized with the result of the bulk delete.