使用枚举(EnumType.STRING)在具有LIKE运算符的实体上执行JPA查询

时间:2012-05-31 00:11:52

标签: java jpa

我能够使用枚举类型存储,检索和查询实体(使用JPA / Hibernate)。枚举字段使用@Enumerated(EnumType.STRING)注释。

是否可以执行"SELECT a FROM MyEntity a WHERE a.myEnum LIKE :param"之类的内容?

我们的想法是让它匹配枚举值字符串(在DB中)与" SYSTEM _%"等模式匹配的任何实体。或"业务_%"。

感谢您提供帮助。

---更新:

当我尝试用此查询时:

`@Query("SELECT e FROM MyEntity e WHERE e.myEnum LIKE :value")`

使用值(表示匹配任何......):

%%

我得到了这个例外:

  Caused by: java.lang.IllegalArgumentException: Parameter value [%%] did not match expected type [mypackage.MyEntity$MyEnum]
        at org.hibernate.ejb.AbstractQueryImpl.validateParameterBinding(AbstractQueryImpl.java:370)
        at org.hibernate.ejb.AbstractQueryImpl.registerParameterBinding(AbstractQueryImpl.java:343)
        at org.hibernate.ejb.QueryImpl.setParameter(QueryImpl.java:374)
        at org.hibernate.ejb.QueryImpl.setParameter(QueryImpl.java:71)

4 个答案:

答案 0 :(得分:2)

绝对。只需使用query.setString("param", "BUSINESS_%");即可。请注意,使用setParameter()而不是setString()会抛出ClassCastException,因为Hibernate会尝试将其强制转换为枚举,但setString()会完全按照您的意愿执行。

答案 1 :(得分:0)

据说org.springframework.orm.hibernate3.HibernateTemplate中有一个快捷方式:

protected void applyNamedParameterToQuery(Query queryObject, String paramName, Object value)
        throws HibernateException {

    if (value instanceof Collection) {
        queryObject.setParameterList(paramName, (Collection) value);
    }
    else if (value instanceof Object[]) {
        queryObject.setParameterList(paramName, (Object[]) value);
    }
    else {
        queryObject.setParameter(paramName, value);
    }
}
如果有一个额外的if if(value instanceoff String)......

,那么

会更好

答案 2 :(得分:0)

作为一种解决方法,您可以通过将模式连接到查询来构建查询。

em.createQuery("SELECT e FROM MyEntity e WHERE e.myEnum LIKE '" + pattern +"'")

它适用于Hibernate和Eclipselink。

但是不要尝试使用pattern来自用户输入,因为以这种方式构造查询很容易受到sql注入攻击。

答案 3 :(得分:0)

我遇到了同样的问题,我做了以下事情:

  • 定义映射到同一数据库列的第二个属性
  • 该属性的类型是字符串
  • 它既不可更新也不可插入
  • 适配枚举属性的set方法
  • 使 String 属性成为只读属性
    @Column(name = "status")
    @Enumerated(EnumType.STRING)
    private StatusEnum status;

    public void setStatus(StatusEnum status) {
        this.status = status;
        this.statusString = status.toString();
    }
    
    @Column(name ="status", updatable = false, insertable = false)
    private String statusString;

现在您可以对 statusString 使用“like”进行查询:

TypedQuery<MyEntity> query = 
    em.createQuery("select e from MyEntity e where e.statusString like 'CLOSED%', MyEntity.class);