EclipseLink не может получить скалярное логическое значение

Следующий запрос критериев JPA выполняется успешно в 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);
}

Он просто предназначен для возврата скалярного логического значения из базы данных MySQL. Соответствующий столбец имеет тип TINYINT(1) в MySQL.

Он генерирует следующий оператор SQL.

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 ?))

Тот же запрос завершается ошибкой в ​​EclipseLink (2.5.1), и в этом случае он ничего не возвращает (ни ошибки, ни исключения). Однако он генерирует правильный оператор SQL следующим образом.

SELECT enabled 
FROM projectdb.user_table
WHERE (LOWER(TRIM(email_id)) = LOWER(TRIM(?)))

bind => [admin]

Соответствующий JPQL такой,

SELECT u.enabled 
FROM UserTable u 
WHERE lower(trim(u.emailId))=lower(trim(:emailId))

также не получает рассматриваемое значение.


Однако он работает с дополнительными столбцами, как показано ниже.

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();

Добавлен один дополнительный столбец root.get(UserTable_.firstName), а тип возвращаемого значения CriteriaQuery изменен с CriteriaQuery<Boolean> на CriteriaQuery<Object[]>.

Столбец определяется следующим образом в соответствующем объекте.

@Basic(optional = false)
@NotNull
@Column(name = "enabled")
private Boolean enabled;  //Getter and setter.

Почему в EclipseLink не задано логическое значение?


person Tiny    schedule 14.05.2014    source источник


Ответы (1)


Это связано с ошибкой EclipseLink https://bugs.eclipse.org/bugs/show_bug.cgi?id=340089, что приводит к тому, что EclipseLink не может отличить значение, возвращаемое из SQL-запроса, от внутренней конструкции, используемой для указания на отсутствие результатов. Выбор другого значения — единственный обходной путь, но он кажется достаточно простым, поэтому немногие люди используют его или просто обходятся без комментариев или голосования за ошибку.

person Chris    schedule 15.05.2014