EclipseLink fails to fetch a scalar Boolean value

一曲冷凌霜 提交于 2019-12-11 12:19:54

问题


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?


回答1:


This is due to EclipseLink bug https://bugs.eclipse.org/bugs/show_bug.cgi?id=340089 which causes EclipseLink to be unable to distinguish the value returned from the SQL query from the construct it uses internally to indicate there were no results. Selecting another value is the only workaround, but it seems simple enough that not many people hit it or just workaround it without commenting or voting for the bug.



来源:https://stackoverflow.com/questions/23651200/eclipselink-fails-to-fetch-a-scalar-boolean-value

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!