I want to find a record by date. In entity and database table, datatype is timestamp. I used Oracle database.
@Entity
public class Request implements Serializable {
@Id
private String id;
@Version
private long version;
@Temporal(TemporalType.TIMESTAMP)
@Column(name = "CREATION_DATE")
private Date creationDate;
public Request() {
}
public Request(String id, Date creationDate) {
setId(id);
setCreationDate(creationDate);
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public long getVersion() {
return version;
}
public void setVersion(long version) {
this.version = version;
}
public Date getCreationDate() {
return creationDate;
}
public void setCreationDate(Date creationDate) {
this.creationDate = creationDate;
}
}
in mian method
public static void main(String[] args) {
RequestTestCase requestTestCase = new RequestTestCase();
EntityManager em = Persistence.createEntityManagerFactory("Criteria").createEntityManager();
em.getTransaction().begin();
em.persist(new Request("005",new Date()));
em.getTransaction().commit();
Query q = em.createQuery("SELECT r FROM Request r WHERE r.creationDate = :creationDate",Request.class);
q.setParameter("creationDate",new GregorianCalendar(2012,12,5).getTime());
Request r = (Request)q.getSingleResult();
System.out.println(r.getCreationDate());
}
In Oracle database record is,
ID CREATION_DATE VERSION
006 05-DEC-12 05.34.39.200000 PM 1
Exception is,
Exception in thread "main" javax.persistence.NoResultException: getSingleResult() did not retrieve any entities.
at org.eclipse.persistence.internal.jpa.EJBQueryImpl.throwNoResultException(EJBQueryImpl.java:1246)
at org.eclipse.persistence.internal.jpa.EJBQueryImpl.getSingleResult(EJBQueryImpl.java:750)
at com.ktrsn.RequestTestCase.main(RequestTestCase.java:29)
The DB type is TIMESTAMP and not DATE, meaning you store exact times.
When using new GregorianCalendar(2012,12,5).getTime() you are quering timestamps that match the given date at 00:00:00.000 and that doesn't exist in your DB
You should either change the DB to store dates instead of timestamps or change your query.
JPA 2 got YEAR, MONTH and DAY functions so you can
SELECT WHERE YEAR(yourdate) = YEAR(dbdate) AND MONTH(yourdate) = MONTH(dbdate) and DAY(yourdate) = DATE(dbdate)
In Criteria API you can do something like this:
Expression<Integer> yourdateYear = cb.function("year", Integer.class, yourdate);
Expression<Integer> yourdateMonth = cb.function("month", Integer.class, yourdate);
Expression<Integer> yourdateDay = cb.function("day", Integer.class, yourdate);
Then combine them with the AND expression and do the same for the date field in db and compare them.
The SIMPLEST WAY to compare date of two datetimes
compare two date and ignore time
WHERE DATE(dbdDate) = DATE(yourDate)
You can use the native query in the jpql.
Example(SQL server):
select table from table where convert(date,mydate)=:date_colum
来源:https://stackoverflow.com/questions/13716586/how-to-find-by-date-from-timestamp-column-in-jpa-criteria