jpa 在实体中使用枚举时进行查询的问题

lstz6jyr  于 12个月前  发布在  其他
关注(0)|答案(3)|浏览(124)

我在一个Question实体中有以下内容:

@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' ],line 1,column 47:invalid enum equal expression,cannot compare enum value of type [myCompnay.application.Status] with a non enum value of type [java.lang.String] . at org.eclipse.persistence.internal.jpa. automaticManagerSetupImpl.deploy(automaticManagerSetupImpl.java:501)
我该如何解决此问题?

hjzp0vay

hjzp0vay1#

我认为你应该使用你的(完全限定的)Status枚举而不是文字值,所以类似这样:(假设你的Status枚举在com.myexample包中)

@NamedQuery(name = "Question.allApproved", 
            query = "SELECT q 
                     FROM Question q 
                     WHERE q.status = com.myexample.Status.APPROVED").

字符串

sg24os4d

sg24os4d2#

您可以在@NamedQuery(或@Query)注解中使用JPQL(Java持久性查询语言),然后在查询中使用param对象的属性。

@NamedQuery(name = "Question.allApproved",
    query = "SELECT q FROM Question q WHERE :#{#q.status.name()} = 'APPROVED'")

字符串

nqwrtyyt

nqwrtyyt3#

自从最初的帖子发布4年以来,有了一些发展。使用spring 4和Hibernate 4,现在可以使用SpEL表达式“欺骗”Hibernate。例如:
enum:

package com.mycompany.enums

public enum Status {
    INITIAL, PENDING, REJECTED, APPROVED, SHIPPED, DELIVERED, COMPLETE;
}

字符串
这里有一个名为'Filter'的 Package 器类,我们将把它传递给存储库过滤方法。

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将这个表达式绑定到查询变量。

相关问题