I've wrote some lines of code that reduce the problem I figured out to a minimum.
@Entity
@Table(name = "test_user")
@UuidGenerator(name = "uuid")
public class User {
@Id
@GeneratedValue(generator = "uuid")
@Column(length = 36, nullable = false)
private String uuid;
@Column(length = 255, nullable = false)
private String name;
@ElementCollection(fetch = FetchType.EAGER)
@CollectionTable(name = "test_user_attribute", joinColumns = { @JoinColumn(name = "user_id", referencedColumnName = "uuid") })
@Column(name = "value", length = 255, nullable = false)
private Set<String> attributes;
public String getUuid() {
return uuid;
}
public void setUuid(final String uuid) {
this.uuid = uuid;
}
public String getName() {
return name;
}
public void setName(final String name) {
this.name = name;
}
public Set<String> getAttributes() {
return attributes;
}
public void setAttributes(final Set<String> attributes) {
this.attributes = attributes;
}
}
final CriteriaBuilder cb = em.getCriteriaBuilder();
final CriteriaQuery<User> cq = cb.createQuery(User.class);
final Root<User> root = cq.from(User.class);
// Select
cq.multiselect(root.get("name"), root.get("attributes"));
// Limits
final TypedQuery<User> tq = em.createQuery(cq);
tq.setFirstResult(0);
tq.setMaxResults(30);
tq.setHint(QueryHints.MAINTAIN_CACHE, HintValues.FALSE);
final List<User> users = tq.getResultList();
The entity User contains an element collection that is linked to a second table, called test_user_attribute. When I want to use the method multiselect() of class CriteriaQuery to create a partial query and want to limit my results using a TypedQuery, the following exception is thrown:
The RuntimeException could not be mapped to a response, re-throwing to the HTTP container
javax.persistence.PersistenceException: java.lang.ClassCastException: org.eclipse.persistence.queries.DirectReadQuery cannot be cast to org.eclipse.persistence.queries.ObjectLevelReadQuery
at org.eclipse.persistence.internal.jpa.QueryImpl.getResultList(QueryImpl.java:480)
at com.test.service.impl.TestUserServiceImpl.getUsers(TestUserServiceImpl.java:108)
...
Caused by: java.lang.ClassCastException: org.eclipse.persistence.queries.DirectReadQuery cannot be cast to org.eclipse.persistence.queries.ObjectLevelReadQuery
at org.eclipse.persistence.mappings.ForeignReferenceMapping.valueFromRowInternal(ForeignReferenceMapping.java:2236)
at org.eclipse.persistence.mappings.ForeignReferenceMapping.valueFromRowInternal(ForeignReferenceMapping.java:2172)
at org.eclipse.persistence.mappings.DirectCollectionMapping.valueFromRowInternalWithJoin(DirectCollectionMapping.java:356)
at org.eclipse.persistence.mappings.DirectCollectionMapping.valueFromRow(DirectCollectionMapping.java:3135)
at org.eclipse.persistence.mappings.ForeignReferenceMapping.readFromRowIntoObject(ForeignReferenceMapping.java:1471)
at org.eclipse.persistence.internal.descriptors.ObjectBuilder.buildAttributesIntoObject(ObjectBuilder.java:461)
at org.eclipse.persistence.internal.descriptors.ObjectBuilder.buildObject(ObjectBuilder.java:1004)
at org.eclipse.persistence.internal.descriptors.ObjectBuilder.buildObject(ObjectBuilder.java:736)
at org.eclipse.persistence.internal.descriptors.ObjectBuilder.buildObjectsInto(ObjectBuilder.java:1340)
at org.eclipse.persistence.queries.ReadAllQuery.executeObjectLevelReadQuery(ReadAllQuery.java:516)
at org.eclipse.persistence.queries.ObjectLevelReadQuery.executeDatabaseQuery(ObjectLevelReadQuery.java:1168)
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.internal.sessions.AbstractSession.internalExecuteQuery(AbstractSession.java:3203)
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.queries.ObjectLevelReadQuery.executeInUnitOfWork(ObjectLevelReadQuery.java:1213)
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)
... 84 more
If the collection is not part of the partial query or the limitation is removed, everything works fine. Am I doing something wrong or is could this be a bug?
I've tested this with EclipseLink 2.4.1 and 2.5.2-M1.