【问题标题】:How to properly convert this SQL case statement to JPA Criteria Query如何将此 SQL 案例语句正确转换为 JPA 标准查询
【发布时间】:2015-10-16 18:09:13
【问题描述】:

我有一个实体如下图;

@Entity
@Table(name="cashhistory")  
@NamedQueries({
    @NamedQuery(name="CashHistory.findAll", query="SELECT c FROM CashHistory c")
})

public class CashHistory implements Serializable {
    private static final long serialVersionUID = 1L;

    @Id
    @GeneratedValue(strategy=GenerationType.IDENTITY)
    @Column(unique=true, nullable=false)
    private int id;

    @Column(nullable=false)
    private boolean funded;

    //... other fields
    //... getters & setters...
}

我需要与以下 MySQL 查询等效的 JPA 标准

select * from cashhistory c 
where (case when (c.funded = true) then 'SUCCESS' else 'FAILED' end) like '%SUCC%'

所以我做了一个这样的 JPA Criteria API 表达式;

CriteriaBuilder cb = em.getCriteriaBuilder();
CriteriaQuery<CashHistory> cq = cb.createQuery(CashHistory.class);
Root<CashHistory> entity = cq.from(CashHistory.class);
cq.select(entity);

Expression<String> expr = cb.selectCase()
    .when(cb.equal(entity.<Boolean>get("funded"), cb.literal(true)), cb.literal("SUCCESS"))
    .otherwise(cb.literal("FAILED")).as(String.class);

cq.where(cb.like(expr, "%SUCC%"));
TypedQuery<CashHistory> query = em.createQuery(cq);
return query.getResultList();

但它会在TypedQuery&lt;CashHistory&gt; query = em.createQuery(cq); 这一行引发以下异常。请参阅下面的 StackTrace;

Caused by: java.lang.IllegalArgumentException: Parameter value [%SUCC%] did not match expected type [java.lang.Character]
    at org.hibernate.ejb.AbstractQueryImpl.validateParameterBinding(AbstractQueryImpl.java:370) [hibernate-entitymanager-4.0.1.Final.jar:4.0.1.Final]
    at org.hibernate.ejb.AbstractQueryImpl.registerParameterBinding(AbstractQueryImpl.java:343) [hibernate-entitymanager-4.0.1.Final.jar:4.0.1.Final]
    at org.hibernate.ejb.QueryImpl.setParameter(QueryImpl.java:370) [hibernate-entitymanager-4.0.1.Final.jar:4.0.1.Final]
    at org.hibernate.ejb.criteria.CriteriaQueryCompiler$1$1.bind(CriteriaQueryCompiler.java:194) [hibernate-entitymanager-4.0.1.Final.jar:4.0.1.Final]
    at org.hibernate.ejb.criteria.CriteriaQueryCompiler.compile(CriteriaQueryCompiler.java:247) [hibernate-entitymanager-4.0.1.Final.jar:4.0.1.Final]
    at org.hibernate.ejb.AbstractEntityManagerImpl.createQuery(AbstractEntityManagerImpl.java:622) [hibernate-entitymanager-4.0.1.Final.jar:4.0.1.Final]
    at org.jboss.as.jpa.container.AbstractEntityManager.createQuery(AbstractEntityManager.java:96) [jboss-as-jpa-7.1.1.Final.jar:7.1.1.Final]

谁能指出我可能做错了什么?

【问题讨论】:

    标签: java mysql jpa


    【解决方案1】:

    您是否从Hibernate 看到过这个问题?

    我也尝试了您的代码,但它似乎不适用于 String 类型的 selectCase,而是使用 Integer 作为解决方法。

    类似这样的代码应该可以工作:

        CriteriaBuilder cb = em.getCriteriaBuilder();
        CriteriaQuery<CashHistory> cq = cb.createQuery(CashHistory.class);
        Root<CashHistory> entity = cq.from(CashHistory.class);
        cq.select(entity);
    
        Expression<Integer> caseExpr = cb.selectCase()
                .when(cb.equal(entity.get("funded"), true), 1)
                .otherwise(2).as(Integer.class);
    
    
        cq.where(cb.equal(caseExpr, 1));
        TypedQuery<CashHistory> query = em.createQuery(cq);
        query.getResultList();
    

    【讨论】:

    • 好的,好点,但我不确定这是否适用于我的情况,因为在这里,我需要比较字符串
    【解决方案2】:

    您必须这样做并专注于命名和本机查询的以下链接 http://www.tutorialspoint.com/jpa/jpa_jpql.htm

    EntityManagerFactory emfactory = Persistence.createEntityManagerFactory(  "Eclipselink_JPA" );
              EntityManager entitymanager = emfactory.createEntityManager();
              Query query = entitymanager.
              createQuery("select c from cashhistory c where (case when (c.funded = true) then 'SUCCESS' else 'FAILED' end) like '%SUCC%'");
              List<String> list = query.getResultList();
    
              for(String e:list) {
                 System.out.println("Object :"+e);
              }
    

    【讨论】:

    • 这不能回答我的问题,因为您提供的当然不是 JPA2.0 CriteriaQuery。也许您没有正确理解我的问题?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-10-31
    • 1970-01-01
    • 2020-05-11
    • 2021-04-11
    • 2012-04-01
    • 2016-01-06
    • 2021-05-09
    相关资源
    最近更新 更多