![](/img/trans.png)
[英]How to convert SQL query with sub query and count to JPA criteria builder
[英]How to properly convert this SQL case statement to JPA Criteria Query
我有一個實體,如下所示;
@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<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]
有人可以指出我可能做錯了什么嗎?
您必須這樣做,並專注於以下鏈接以進行命名查詢和本機查詢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);
}
您是否從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();
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.