在实体中使用Enum时进行查询的问题
我在问题实体中具有以下内容:
@NamedQuery(name = "Question.allApproved", query = "SELECT q FROM Question q WHERE q.status = 'APPROVED'")
和
@Enumerated(EnumType.STRING) private Status status; // usual accessors
我得到这个例外:
exception说明:编译查询时出错[Question.countApplied:
SELECT COUNT(q) FROM Question q WHERE q.status = 'APPROVED'
],第1行,第47列:无效枚举等于expression式,无法比较types[myCompnay.application.Status]
枚举值[myCompnay.application.Status]
与一个非枚举值的types[java.lang.String]
。 在org.eclipse.persistence.internal.jpa.EntityManagerSetupImpl.deploy(EntityManagerSetupImpl.java:501)
我该如何解决?
我认为你应该使用你的(完全合格的) Status
枚举而不是字面值,所以像这样:(假设你的Status
枚举在com.myexample
包中)
@NamedQuery(name = "Question.allApproved", query = "SELECT q FROM Question q WHERE q.status = com.myexample.Status.APPROVED").
请在application.properties中使用下面的属性logging.level.org.hibernate.type.descriptor.sql.BasicBinder = TRACE
4年以来,有一些发展。 使用Spring 4和Hibernate 4现在可以使用SpELexpression式来“诱骗”Hibernate了。 例如:
枚举:
package com.mycompany.enums public enum Status { INITIAL, PENDING, REJECTED, APPROVED, SHIPPED, DELIVERED, COMPLETE; }
这是一个名为“Filter”的包装类,我们将其传递给存储库过滤方法。
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类作为单个参数,并将查询翻译成似乎是文字和SpELexpression式混合的状态对象:
存储库:
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); }
这完美的工作,但由于一些奇怪的原因,我还没有想出来,如果你在Hibernate中启用SQLdebugging,并打开活页夹日志logging,您将无法看到Hibernate绑定此expression式查询variables。