javahibernatecascading-deletes

IllegalArgumentException: node to traverse cannot be null


My DELETE query is failing.

Here's my code:

String q = "SELECT p.id FROM Person p, DomainGroup g WHERE 
   p member of g.coordinators" + " AND g.id = :groupId 
   AND p.id = :personId";
                
List<Long> test = getEntityManager()
  .createQuery(q).setParameter("groupId", followingId)
  .setParameter("personId", followerId).getResultList();
                
log.debug("test = " + test);
                
String deleteGroupCoordinatorQuery = 
  "DELETE FROM Person p, DomainGroup g WHERE p member 
     of g.coordinators" + " AND g.id = :groupId 
        AND p.id = :personId";

List<Long> test = getEntityManager()
      .createQuery(deleteGroupCoordinatorQuery).setParameter
      ("groupId", followingId)
      .setParameter("personId", followerId).executeUpdate();

Output:

test = [1,2,3]

2012-10-26 13:44:56,437 ERROR org.company.commons.server.service.ServiceActionController - Error occurred performing transaction. java.lang.IllegalArgumentException: node to traverse cannot be null!
        at org.hibernate.hql.ast.util.NodeTraverser.traverseDepthFirst(NodeTraverser.java:55)
        at org.hibernate.hql.ast.QueryTranslatorImpl.parse(QueryTranslatorImpl.java:280)
        at org.hibernate.hql.ast.QueryTranslatorImpl.doCompile(QueryTranslatorImpl.java:182)
        at org.hibernate.hql.ast.QueryTranslatorImpl.compile(QueryTranslatorImpl.java:136)

Solution

  • You define multiple "query roots" (Person p and DomainGroup g), but a DELETE query can have only one such root.

    You want something like:

    delete Person p
    where p.id in (
        select c.id
        from DomainGroup g
            join g.coordinators c
        where g.id = :groupId
          and c.id = :personId
    )
    

    or

    delete Person p
    where p.id = :personId
      and p.id in (
        select c.id
        from DomainGroup g
            join g.coordinators c
        where g.id = :groupId
    )