В сущности вопроса у меня есть следующее:
@NamedQuery(name = "Question.allApproved",
query = "SELECT q FROM Question q WHERE q.status = 'APPROVED'")
и
@Enumerated(EnumType.STRING)
private Status status;
// usual accessors
Я получаю это исключение:
Описание исключения: Ошибка компиляции запроса [Question.countApproved:
SELECT COUNT(q) FROM Question q WHERE q.status = 'APPROVED'
], строка 1, столбец 47: недопустимое выражение enum equal, невозможно сравнить значение перечисления типа[myCompnay.application.Status]
со значением типа, отличным от перечисления[java.lang.String]
. в org.eclipse.persistence.internal.jpa.EntityManagerSetupImpl.deploy (EntityManagerSetupImpl.java:501)
Как это исправить?
java
jakarta-ee
jpa
LuckyLuke
источник
источник
Ответы:
Я думаю, вам следует использовать свое (полностью квалифицированное)
Status
перечисление вместо буквального значения, поэтому что-то вроде этого: (при условии, что вашеStatus
перечисление находится вcom.myexample
пакете)@NamedQuery(name = "Question.allApproved", query = "SELECT q FROM Question q WHERE q.status = com.myexample.Status.APPROVED").
источник
@Query
аннотации вы говорите?fully qualified
более важно, как я думал.Через 4 года после первого поста произошли некоторые изменения. Используя Spring 4 и Hibernate 4, теперь можно «обмануть» Hibernate, используя выражение SpEL. Например:
Перечисление:
package com.mycompany.enums public enum Status { INITIAL, PENDING, REJECTED, APPROVED, SHIPPED, DELIVERED, COMPLETE; }
Вот класс-оболочка под названием «Фильтр», который мы передадим методу фильтрации репозитория.
package com.mycompany.enums public class Filter implements Serializable { /** The id of the filtered item */ private Integer id; /** The status of the filtered item */ private Status status; // more filter criteria here... // getters, setters, equals(), hashCode() - omitted for brevity /** * Returns the name of the status constant or null if the status is null. This is used in the repositories to filter * queries by the status using a the SPEL (T) expression, taking advantage of the status qualified name. For example: * {@code :#{T(com.mycompany.enums.Status).#filter.statusName}} * * @return the status constant name or null if the status is null */ public String getStatusName() { return null == status ? status : status.name(); } }
Наконец, в репозитории мы теперь можем использовать класс Filter в качестве единственного параметра и заставить запрос переводить то, что кажется смесью литералов и выражений SpEL, в объект Status:
Репозиторий:
package com.mycompany.repository @Repository public interface OrderRepository extends CrudRepository<Order, Integer> { @Query("SELECT o from Order o " + "WHERE o.id = COALESCE(:#{#filter.id},o.id) " + "AND o.status = COALESCE(:#{T(com.mycompany.enums.Status).#filter.statusName},o.status)") public List<Order> getFilteredOrders(@Param(value = "filter") Filter filter); }
Это работает отлично, но по какой-то странной причине я еще не понял, если вы включите отладку SQL в Hibernate и включите ведение журнала привязки, вы не сможете увидеть, как Hibernate связывает это выражение с переменными запроса.
источник
Используйте свойство ниже в application.properties logging.level.org.hibernate.type.descriptor.sql.BasicBinder = TRACE
источник