我的问题实体中有以下内容:
@NamedQuery(name = "Question.allApproved",
query = "SELECT q FROM Question q WHERE q.status = 'APPROVED'")
和
@Enumerated(EnumType.STRING)
private Status status;
// usual accessors
我遇到了这个异常:
异常描述:编译查询时出错 [Question.countApproved:
],第 1 行,第 47 列:无效枚举等于 表达式,无法比较类型的枚举值SELECT COUNT(q) FROM Question q WHERE q.status = 'APPROVED'
具有非枚举值 类型为[myCompnay.application.Status]
。在 org.eclipse.persistence.internal.jpa.EntityManagerSetupImpl.deploy(EntityManagerSetupImpl.java:501)[java.lang.String]
我该如何解决这个问题?
我认为你应该使用你的(完全限定的)
Status
枚举而不是字面值,所以像这样:(假设你的Status
枚举位于com.myexample
包中)
@NamedQuery(name = "Question.allApproved",
query = "SELECT q
FROM Question q
WHERE q.status = com.myexample.Status.APPROVED").
可以在@NamedQuery(或@Query)注解中使用JPQL(Java持久性查询语言),然后在查询中使用param对象的属性。
@NamedQuery(name = "Question.allApproved", 查询=“从问题q WHERE中选择q:#{#q.status.name()} ='批准'”)
自首次发布以来已有 4 年了,取得了一些进展。使用 spring 4 和 Hibernate 4 现在可以使用 SpEL 表达式来“欺骗”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 类作为单个参数,并使查询将看似文字和 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);
}
这工作得很好,但由于一些奇怪的原因我还没有弄清楚,如果你在 Hibernate 中启用 SQL 调试并打开绑定器日志记录,你将无法看到 Hibernate 将此表达式绑定到查询变量。