2015-10-16 178 views
0

我有一個實體,如下所示;如何將此SQL語句正確轉換爲JPA標準查詢

@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... 
} 

我需要的JPA標準相當於下面的MySQL查詢

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

所以我做了這樣的JPA標準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<CashHistory> 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] 

有人可以請指我到哪裏我可能做錯了什麼?

回答

0

你必須做這樣的,集中在以下鏈接命名和本地查詢 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); 
      } 
+0

這不回答我的問題,因爲你已經肯定提供哪些不是JPA2.0 CriteriaQuery中。也許你沒有正確理解我的問題? – CodeBurner

0

你從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(); 
+0

好的,好點,但我不確定這會適用於我的情況,因爲在這裏,我需要比較字符串 – CodeBurner