The following JPA criteria query succeeds on Hibernate (4.2.7 final).
CriteriaBuilder criteriaBuilder=entityManager.getCriteriaBuilder();
CriteriaQuery<Boolean>criteriaQuery=criteriaBuilder.createQuery(Boolean.class);
Root<UserTable> root = criteriaQuery.from(entityManager.getMetamodel().entity(UserTable.class));
criteriaQuery.multiselect(root.get(UserTable_.enabled));
ParameterExpression<String>parameterExpression=criteriaBuilder.parameter(String.class);
criteriaQuery.where(criteriaBuilder.equal(criteriaBuilder.lower(criteriaBuilder.trim(root.get(UserTable_.emailId))), criteriaBuilder.lower(criteriaBuilder.trim(parameterExpression))));
List<Boolean> list = entityManager.createQuery(criteriaQuery).setParameter(parameterExpression, "admin").getResultList();
for(Boolean o:list)
{
System.out.println("enabled : "+o);
}
It is simply meant to return a scalar Boolean value from MySQL database. The corresponding column is of type TINYINT(1)
in MySQL.
It generate the following SQL statement.
SELECT
usertable0_.enabled as col_0_0_
FROM
social_networking.user_table usertable0_
WHERE
lower(trim(BOTH FROM usertable0_.email_id))=lower(trim(BOTH FROM ?))
The same query fails on EclipseLink (2.5.1) in which case it returns nothing (no error, no exception). It however, generates a correct SQL statement as follows.
SELECT enabled
FROM projectdb.user_table
WHERE (LOWER(TRIM(email_id)) = LOWER(TRIM(?)))
bind => [admin]
The corresponding JPQL like so,
SELECT u.enabled
FROM UserTable u
WHERE lower(trim(u.emailId))=lower(trim(:emailId))
also doesn't get the value in question.
It however, works with additional columns as shown below.
CriteriaBuilder criteriaBuilder=entityManager.getCriteriaBuilder();
CriteriaQuery<Object[]>criteriaQuery=criteriaBuilder.createQuery(Object[].class);
Root<UserTable> root = criteriaQuery.from(entityManager.getMetamodel().entity(UserTable.class));
criteriaQuery.multiselect(root.get(UserTable_.enabled), root.get(UserTable_.firstName));
ParameterExpression<String>parameterExpression=criteriaBuilder.parameter(String.class);
criteriaQuery.where(criteriaBuilder.equal(criteriaBuilder.lower(criteriaBuilder.trim(root.get(UserTable_.emailId))), criteriaBuilder.lower(criteriaBuilder.trim(parameterExpression))));
List<Object[]> list = entityManager.createQuery(criteriaQuery).setParameter(parameterExpression, userName).getResultList();
One extra column root.get(UserTable_.firstName)
is added and the return type of CriteriaQuery
is changed from CriteriaQuery<Boolean>
to CriteriaQuery<Object[]>
.
The column is defined as follows in the corresponding entity.
@Basic(optional = false)
@NotNull
@Column(name = "enabled")
private Boolean enabled; //Getter and setter.
Why doesn't it given a Boolean value in EclipseLink?