I have this class,
@Entity
public class Message {
@Id @GeneratedValue(strategy=GenerationType.IDENTITY)
private long id;
@Column( nullable = false )
private String mobile;
@Column( nullable = false )
private String message;
@Column( nullable = false )
private Lang lang;
@Column( nullable = false )
private int status;
@Column( nullable = false )
private Calendar creationDate;
...
}
and I would like to be able to query the table with optional parameters from a form. I'm using JPA 2.1 and Hibernate. Is there way to do this without multiple query statements or without tightly coupling my application to hibernate or the specific database that i'm using?
Here is the form i'm using:
<form action="${pageContext.request.contextPath}/search">
<label>From</label>
<input type="datetime" placeholder="dd/mm/yy hh/mm" name="from" required>
<label>To</label>
<input type="datetime" placeholder="dd/mm/yy hh/mm" name="to" required>
<select name="lang">
<option value="english">English</option>
<option value="arabic">Arabic</option>
</select>
<input type="tel" placeholder="Recipient" name="recipient">
<select name="status">
<option value="new">New</option>
<option value="picked">Picked</option>
<option value="sent">Sent</option>
<option value="rejected">Rejected</option>
</select>
<input type="submit" value="Search">
UPDATE::::::::::::::::::::::::::::
I tried this:
public List<Message> getMessages(Calendar fromDate, Calendar toDate, String lang, String recipient, String status) {
/*TypedQuery<Message> query = em.createQuery(
"SELECT e FROM Message e WHERE e.creationDate BETWEEN :fromDate AND :toDate", Message.class);
query.setParameter("fromDate", fromDate);
query.setParameter("toDate", toDate);
List<Message> list = query.getResultList();
return list;*/
List<Predicate> predicates = new ArrayList<>();
CriteriaBuilder cb = em.getCriteriaBuilder();
CriteriaQuery<Message> query = cb.createQuery(Message.class);
Root<Message> root = query.from(Message.class);
predicates.add(cb.between(root.get("creationDate"), fromDate, toDate));
if (lang != null && !lang.equalsIgnoreCase("any")) {
predicates.add(cb.equal(root.get("lang"), lang));
}
if (recipient != null && !recipient.equals("")) {
predicates.add(cb.equal(root.get("mobile"), recipient));
}
if (status != null && !status.equalsIgnoreCase("any")) {
predicates.add(cb.equal(root.get("mobile"), recipient));
}
query.where(cb.and(predicates.toArray(new Predicate[predicates.size()])));
List<Message> list = em.createQuery(query).getResultList();
return list;
}
but I'm getting the following error:
java.lang.IllegalArgumentException: Parameter value [0] did not match expected type [entity.Lang (n/a)]
at org.hibernate.jpa.spi.BaseQueryImpl.validateBinding(BaseQueryImpl.java:897)
at org.hibernate.jpa.internal.QueryImpl.access$000(QueryImpl.java:61)
at org.hibernate.jpa.internal.QueryImpl$ParameterRegistrationImpl.bindValue(QueryImpl.java:235)
at org.hibernate.jpa.spi.BaseQueryImpl.setParameter(BaseQueryImpl.java:638)
at org.hibernate.jpa.spi.AbstractQueryImpl.setParameter(AbstractQueryImpl.java:163)
at org.hibernate.jpa.spi.AbstractQueryImpl.setParameter(AbstractQueryImpl.java:32)
at org.hibernate.jpa.criteria.compile.CriteriaCompiler$1$1.bind(CriteriaCompiler.java:109)
at org.hibernate.jpa.criteria.CriteriaQueryImpl$1.buildCompiledQuery(CriteriaQueryImpl.java:369)
at org.hibernate.jpa.criteria.compile.CriteriaCompiler.compile(CriteriaCompiler.java:130)
at org.hibernate.jpa.spi.AbstractEntityManagerImpl.createQuery(AbstractEntityManagerImpl.java:699)
at dao.MessageDAO.getMessages(MessageDAO.java:63)