I'm trying to 'translate' the following jpql query using criteria builder.
select p.name, a from Person p left outer join p.address a
in the select clause I want to include the joined entity address.
Using criteria builder api I did this:
Person p = new Person();
p.setName("person");
em.persist(p);
CriteriaBuilder cb = em.getCriteriaBuilder();
CriteriaQuery<Object[]> cq = cb.createQuery(Object[].class);
Root<Person> root = cq.from(Person.class);
Join<Person, Address> join = root.join("address", JoinType.LEFT);
cq.multiselect(
root.get("name"),
join
);
TypedQuery<Object[]> q = em.createQuery(cq);
List resultList = q.getResultList();
The persisted person doesn't have an address but a left join should return the person and 'null' as address. The jpql query works as expected but using the critera api I got a strange error because eclipse link tries to create the Address entity and complains about the nullability of the primary key.
Am I missing something ?
In attachment you could find a zip with the project with a runnable Main class (jar are not included because it would exceed file size).
This is the error:
[EL Warning]: 2013-12-05 19:56:54.391--UnitOfWork(5232909)--Exception [EclipseLink-6044] (Eclipse Persistence Services - 2.5.1.v20130918-f2b9fc5): org.eclipse.persistence.exceptions.QueryException
Exception Description: The primary key read from the row [DatabaseRecord(
ADDRESS.ID => null
ADDRESS.STREET => null)] during the execution of the query was detected to be null. Primary keys must not contain null.
Query: ReportQuery(referenceClass=Person sql="SELECT t0.NAME, t1.ID, t1.STREET FROM PERSON t0 LEFT OUTER JOIN ADDRESS t1 ON (t1.ID = t0.ADDRESS_ID)")
Exception in thread "main" javax.persistence.PersistenceException: Exception [EclipseLink-6044] (Eclipse Persistence Services - 2.5.1.v20130918-f2b9fc5): org.eclipse.persistence.exceptions.QueryException
Exception Description: The primary key read from the row [DatabaseRecord(
ADDRESS.ID => null
ADDRESS.STREET => null)] during the execution of the query was detected to be null. Primary keys must not contain null.
Query: ReportQuery(referenceClass=Person sql="SELECT t0.NAME, t1.ID, t1.STREET FROM PERSON t0 LEFT OUTER JOIN ADDRESS t1 ON (t1.ID = t0.ADDRESS_ID)")
at org.eclipse.persistence.internal.jpa.QueryImpl.getResultList(QueryImpl.java:480)
at it.egesuato.model.Main.main(Main.java:41)
Caused by: Exception [EclipseLink-6044] (Eclipse Persistence Services - 2.5.1.v20130918-f2b9fc5): org.eclipse.persistence.exceptions.QueryException
Exception Description: The primary key read from the row [DatabaseRecord(
ADDRESS.ID => null
ADDRESS.STREET => null)] during the execution of the query was detected to be null. Primary keys must not contain null.
Query: ReportQuery(referenceClass=Person sql="SELECT t0.NAME, t1.ID, t1.STREET FROM PERSON t0 LEFT OUTER JOIN ADDRESS t1 ON (t1.ID = t0.ADDRESS_ID)")
at org.eclipse.persistence.exceptions.QueryException.nullPrimaryKeyInBuildingObject(QueryException.java:921)
at org.eclipse.persistence.internal.descriptors.ObjectBuilder.buildObject(ObjectBuilder.java:715)
at org.eclipse.persistence.internal.descriptors.ObjectBuilder.buildObject(ObjectBuilder.java:688)
at org.eclipse.persistence.queries.ReportQueryResult.processItem(ReportQueryResult.java:218)
at org.eclipse.persistence.queries.ReportQueryResult.buildResult(ReportQueryResult.java:144)
at org.eclipse.persistence.queries.ReportQueryResult.<init>(ReportQueryResult.java:79)
at org.eclipse.persistence.queries.ReportQuery.buildObject(ReportQuery.java:594)
at org.eclipse.persistence.queries.ReportQuery.buildObjects(ReportQuery.java:645)
at org.eclipse.persistence.queries.ReportQuery.executeDatabaseQuery(ReportQuery.java:848)
at org.eclipse.persistence.queries.DatabaseQuery.execute(DatabaseQuery.java:899)
at org.eclipse.persistence.queries.ObjectLevelReadQuery.execute(ObjectLevelReadQuery.java:1127)
at org.eclipse.persistence.queries.ReadAllQuery.execute(ReadAllQuery.java:403)
at org.eclipse.persistence.queries.ObjectLevelReadQuery.executeInUnitOfWork(ObjectLevelReadQuery.java:1215)
at org.eclipse.persistence.internal.sessions.UnitOfWorkImpl.internalExecuteQuery(UnitOfWorkImpl.java:2896)
at org.eclipse.persistence.internal.sessions.AbstractSession.executeQuery(AbstractSession.java:1793)
at org.eclipse.persistence.internal.sessions.AbstractSession.executeQuery(AbstractSession.java:1775)
at org.eclipse.persistence.internal.sessions.AbstractSession.executeQuery(AbstractSession.java:1740)
at org.eclipse.persistence.internal.jpa.QueryImpl.executeReadQuery(QueryImpl.java:258)
at org.eclipse.persistence.internal.jpa.QueryImpl.getResultList(QueryImpl.java:469)
... 1 more