robbit
robbit

Reputation: 427

JPA criteria api join: CAN_NOT_JOIN_TO_BASIC

I am getting an exception CAN_NOT_JOIN_TO_BASIC on my JPA criteria API query:

   @Entity
   public class Connection {
       @Id
       private String id;
       private String sourceNodeId;
       private String targetNodeId;
   }

    @Entity
    public class Node {
        @Id
        private String id;
        private String graphId;
    }

I want to retrieve all connections belonging to a specific graph. The query:

    final CriteriaBuilder cb = entityManager.getCriteriaBuilder();
    CriteriaQuery<Connection> query = cb.createQuery(Connection.class);
    Root<Connection> connection = query.from(Connection.class);
    Join<Connection,Node> node = connection.join("sourceNodeId");
    TypedQuery<Connection> typedQuery = entityManager.createQuery(query
            .select(connection)
            .where(cb.equal(joiningSequenceObject.get("graphId"), someId)));

    return typedQuery.getResultList();

What am I doing wrong? Help appreciated!

Upvotes: 0

Views: 649

Answers (1)

Nikos Paraskevopoulos
Nikos Paraskevopoulos

Reputation: 40308

In order to use the JPQL JOIN, or the equivalent From.join() methods from the criteria API, the entities must be joined through a relationship. So one reasonable option is to relate Connection with Node.

If that is impossible, you can use the simple join syntax:

SELECT c
FROM Connection c, Node n
WHERE (c.sourceNodeId = n.id OR c.targetNodeId = n.id)
  AND n.graphId = :graphId

Or in criteria API something like:

final CriteriaBuilder cb = entityManager.getCriteriaBuilder();
CriteriaQuery<Connection> query = cb.createQuery(Connection.class);
Root<Connection> connection = query.from(Connection.class);
Root<Node> node = query.from(Node.class);
TypedQuery<Connection> typedQuery = entityManager.createQuery(query
        .select(connection)
        .where(
            cb.and(
                cb.or(
                    cb.equal(connection.get("sourceNodeId"), node.get("id")),
                    cb.equal(connection.get("targetNodeId"), node.get("id"))
                ),
                cb.equal(node.get("graphId"), someId)
            )
        );

return typedQuery.getResultList();

Upvotes: 1

Related Questions