【发布时间】:2014-01-26 09:20:53
【问题描述】:
我正在尝试使用 JPA 标准构建一个动态查询,以使用高级搜索表单中的参数从 gae-datastore 检索数据。该表单有五个字段,类型、最小金额、最大金额、从日期和到日期。类型,最小和最大数量,工作得很好,但是对于日期字段我有这个例外
严重:javax.persistence.PersistenceException:在“(DN_THIS.author = '18580476422013912411')和(DN_THIS.date >= Wed Jan 01 00:00:00 CET 2014)和(DN_THIS)中的字符 68 处预期为 ')' .date
这是我的 DAO 中引发异常的方法:
public List<Outlay> findByParameters(String author, String page, String pageSize,
String type, String minAmount, String maxAmount, String fromDate, String toDate)
throws PersistenceException, ParseException {
EntityManager em = EMF.get().createEntityManager();
CriteriaBuilder cb = em.getCriteriaBuilder();
CriteriaQuery<Outlay> cq = cb.createQuery(Outlay.class);
Root<Outlay> outlay = cq.from(Outlay.class);
List<Predicate> predicates = new ArrayList<Predicate>();
if(author != null && !author.isEmpty()) {
predicates.add(cb.equal(outlay.<String>get("author"), author));
}
if(type != null && !type.isEmpty()) {
predicates.add(cb.equal(outlay.<String>get("type"), type));
}
if(minAmount != null && !minAmount.isEmpty()) {
Double min = Double.parseDouble(minAmount);
predicates.add(cb.ge(outlay.<Double>get("amount"), min));
}
if(maxAmount != null && !maxAmount.isEmpty()) {
Double max = Double.parseDouble(maxAmount);
predicates.add(cb.le(outlay.<Double>get("amount"), max));
}
SimpleDateFormat formatter = new SimpleDateFormat("yyyy/MM/dd");
if(fromDate != null && !fromDate.isEmpty()) {
Date from = formatter.parse(fromDate);
log.info("From: " + formatter.format(from));
predicates.add(cb.greaterThanOrEqualTo(outlay.<Date>get("date"), from));
}
if(toDate != null && !toDate.isEmpty()) {
Date to = formatter.parse(toDate);
log.info("To: " + formatter.format(to));
predicates.add(cb.lessThanOrEqualTo(outlay.<Date>get("date"), to));
}
cq.select(outlay).where(predicates.toArray(new Predicate[]{}));
log.info("Query: " + cq.toString());
TypedQuery<Outlay> query = em.createQuery(cq);
Integer index = 0;
if(page != null && !page.isEmpty()) {
index = Integer.parseInt(page);
}
Integer step = 10;
if(pageSize != null && !pageSize.isEmpty()) {
step = Integer.parseInt(pageSize);
}
query.setFirstResult(index * step);
query.setMaxResults(step);
List<Outlay> outlayList = new ArrayList<Outlay>();
try {
outlayList = query.getResultList();
log.info("Retrieved " + outlayList.size() + " Outlay");
} finally {
em.close();
}
return outlayList;
}
这是结果查询
SELECT DN_THIS FROM com.mycompany.model.Outlay DN_THIS WHERE (DN_THIS.author = '18580476422013912411') AND (DN_THIS.date >= Wed Jan 01 00:00:00 CET 2014) AND (DN_THIS.date
这是我的实体
import java.io.Serializable;
import java.util.Date;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Temporal;
import javax.persistence.TemporalType;
@Entity
public class Outlay implements Serializable {
private static final long serialVersionUID = 1L;
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String author;
private String type;
private Double amount;
private Date date;
private String description;
Outlay() { }
public Outlay(String author, String type, Double amount, Date date,
String description) {
super();
this.author = author;
this.type = type;
this.amount = amount;
this.date = date;
this.description = description;
}
public long getId() {
return id;
}
public String getAuthor() {
return author;
}
public void setAuthor(String author) {
this.author = author;
}
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
public Double getAmount() {
return amount;
}
public void setAmount(Double amount) {
this.amount = amount;
}
@Temporal(TemporalType.DATE)
public Date getDate() {
return date;
}
public void setDate(Date date) {
this.date = date;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
@Override
public String toString() {
return "Outlay [id=" + id + ", author=" + author + ", type=" + type
+ ", amount=" + amount + ", date=" + date + "]";
}
}
奇怪的是,我的 DAO 中也有类似的方法
public Long countByParameters(String author, String type, String minAmount,
String maxAmount, String fromDate, String toDate)
throws PersistenceException, ParseException {
EntityManager em = EMF.get().createEntityManager();
CriteriaBuilder cb = em.getCriteriaBuilder();
CriteriaQuery<Long> cq = cb.createQuery(Long.class);
Root<Outlay> outlay = cq.from(Outlay.class);
List<Predicate> predicates = new ArrayList<Predicate>();
if(author != null && !author.isEmpty()) {
predicates.add(cb.equal(outlay.<String>get("author"), author));
}
if(type != null && !type.isEmpty()) {
predicates.add(cb.equal(outlay.<String>get("type"), type));
}
if(minAmount != null && !minAmount.isEmpty()) {
Double min = Double.parseDouble(minAmount);
predicates.add(cb.ge(outlay.<Double>get("amount"), min));
}
if(maxAmount != null && !maxAmount.isEmpty()) {
Double max = Double.parseDouble(maxAmount);
predicates.add(cb.le(outlay.<Double>get("amount"), max));
}
SimpleDateFormat formatter = new SimpleDateFormat("yyyy/MM/dd");
if(fromDate != null && !fromDate.isEmpty()) {
Date from = formatter.parse(fromDate);
log.info("From: " + formatter.format(from));
predicates.add(cb.greaterThanOrEqualTo(outlay.<Date>get("date"), from));
}
if(toDate != null && !toDate.isEmpty()) {
Date to = formatter.parse(toDate);
log.info("To: " + formatter.format(to));
predicates.add(cb.lessThanOrEqualTo(outlay.<Date>get("date"), to));
}
cq.select(cb.count(outlay)).where(predicates.toArray(new Predicate[]{}));
log.info("Query: " + cq.toString());
Long count = 0l;
try {
count = em.createQuery(cq).getSingleResult();
log.info("OutlayList " + count + " size");
} finally {
em.close();
}
return count;
}
这很完美。
我的设置是 GAE SDK 1.8.9、JPA 2.0、datanucleus-core 3.1.3、datanucleus-jpa-api 3.1.3 和 datanucleus-appengine-2.1.2。
任何帮助将不胜感激! 提前致谢。
【问题讨论】:
标签: google-cloud-datastore jpa-2.0 criteria datanucleus