I have the following query:
#NamedQuery(name = "User.findByParams", query=
"SELECT *
FROM User user
WHERE user.name type = :inputType")
And I wish to add AND statement, that will take place only if the inputs are supplied:
#NamedQuery(name = "User.findByParams", query=
"SELECT *
FROM User user
WHERE user.name type = :inputType AND (:ageInput != null AND user.age > :ageInput")
It means that if the ageInput is supplied, filter by it as well. If not- ignore this param. Any ideas?
Any ideas?
As the previous speakers wrote, you can use Criteria
Criteria criteria = createCriteria()
.add(Restrictions.eq("type", type));
if (ageInput != null) {
criteria.add(Restrictions.eq("ageInput", ageInput));
}
List<User> list = criteria.list();
or SQLQuery
String sql = "SELECT * " +
"FROM User user " +
"WHERE user.type = :inputType ";
sql += (ageInput != null) ? "AND ageInput = :ageInput " : "";
Query query = sessionFactory.getCurrentSession().createSQLQuery(sql)
.setParameter("inputType", inputType);
if(ageInput != null) {
query.setParameter("ageInput", ageInput);
}
return (List<User>) query.list();
You will have to check if ageInput is supplied or not in code and will have to call different methods accordingly.
Means if ageInput is supplied then you will have to call a method having ageInput constraint o/w call method which do not have ageInput constraint.
Alternatively, you can use predicates and execute a query.
Related
Currently I am doing it like this:
List<Table1Entity> findAllMatchingEntities(Table1Entity table1Entity) {
String queryString = "SELECT table1.* FROM table1 "
+ "JOIN table2 t2 ON table1.id=t2.table1_id";
if (table1Entity.getName() != null) {
queryString +=" where name like ?";
}
Query query = em.createNativeQuery(queryString, Table1Entity.class);
if (table1Entity.getName() != null) {
query.setParameter(1, table1Entity.getName())
}
return query.getResultedList();
}
If I want to check more parameters in this join this will quickly turn into a lot of if statements and it would be really complicated to set parameters correctly.
I know I can check parameters with criteria Builder API like this:
if(table1Entity.getName() != null) {
table1EntitySpecification = (root, query, criteriaBuilder)
-> criteriaBuilder.like(
criteriaBuilder.lower(root
.get("name")),
("%" + table1Entity.getName() + "%")
.toLowerCase());;
}
and after that get them all with:
findAll(table1EntitySpecification) with findAll from simpleJPARepository. Now I can chain them together with .or or .and etc. and avoid setting the parameter and checking for null second time.
But how do I do join with criteria APi?
I know I can have in my #Repository something like this:
#Query(value = "SELECT table1.* FROM table1 JOIN table2 t2 ON table1.id=t2.table1_id", nativeQuery = true)
List<Table1Entity> findAllMatchingEntities(Table1Entity table1Entity);
But since name is optional (can be null) I can't just leave it in #Query.
What is the best solution here to avoid using native query and in case of having to check many parameters to avoid using if statements?
I don't know if I fully get your question, but regarding the possibility of nulls, and using the CRUD repository, you can always do a null check before like:
#Query(value = "SELECT table1.* FROM table1 JOIN table2 t2 ON table1.id=t2.table1_id WHERE table1.id is not null", nativeQuery = true)
List<Table1Entity> findAllMatchingEntities(Table1Entity table1Entity);
Depending on what you are trying to achieve, you can always compose the query with similar checks like (not related to your code):
#Query("SELECT c FROM Certificate c WHERE (:id is null or upper(c.id) = :id) "
+ "and (:name is null or upper(c.name) = :name)")
List<Table1> findStuff(#Param("id") String id,
#Param("name") String name);
I am trying to select from db using HQL with two conditions as below:
String hql = "from User u where u.login=? and u.password=?";
Query query = sessionFactory.getCurrentSession().createQuery(hql);
System.out.println(query);
query.setString(0, u);
query.setString(1, p);
#SuppressWarnings("unchecked")
List<User> listUser = (List<User>) query.list();
System.out.println(listUser);
if (listUser != null && !listUser.isEmpty()) {
return true;
}
return false;
But I am getting empty result. I tried by giving only one condition , then it is giving proper result. (i.e. from User u where u.login=?). How to achieve this with two conditions?
am trying to form a query based on parameters, if the parameters for WHERE clause is null or not. it seems to be a huge code if i do this on if and else. Is there any other smart way to this??
example :
String query = "SELECT CUSTOMER_NAME FROM CUSTOMER_TABLE WHERE ";
if(cust_id !=null && !(cust_id.trim().equalsIgnoreCase("")))
{
query = query + "cust_id='"+cust_id+"'";
}
else
{
}
checking all the columns like this, the code is looking like a mess, please let me know if there is an other way to do this
adding to the above question :
I also have the parameters for like operator
example
if(strCustName!=null)
{
String query = "SELECT * FROM CUSTOMER WHERE CUSTOMER_NAME LIKE '"+strCustName+"';
}
You can use NamedParameterJDBCTemplate
And your query could be
... WHERE (cust_id=:custIdParam OR :custIdParam is null)
AND (another_column=:another_param OR :another_param is null)
UPDATE:
String sqlstr = "select * from the_table where lastname like :lastname or :lastname is null"
NamedParameterJdbcTemplate jt = new NamedParameterJdbcTemplate(datasource);
Map namedParameters = new HashMap();
namedParameters.put("lastname", "%test%");
SqlRowSet result = jt.queryForRowSet( sqlstr ,namedParameters );
from the link
need a help to create hibernate query that table is jdwCustomerTlrdRef and it should take all the operation_spec = customer name. the method should return sysId.
Here is the code to review. Please help me i am new to this hibernate query.
public getCustomerTlrdRef(BigDecimal sysId) {
System.out.println("---- getAllCustomerTlrdRef " );
String query = "from JdwCustomerTlrdRef as jdwCustomerTlrdRef where jdwCustomerTlrdRef.operation_spec= '+customer_name+'";
Query q = getSessionFactory().getCurrentSession().createQuery(query);
List<JdwCustomerTlrdRef> customerTlrdRefSysId = q.list();
System.out.println(" List size: " + customerTlrdRefSysId.size());
return customerTlrdRefSysId;
}
This should work.
String query = "from JdwCustomerTlrdRef jdwCustomerTlrdRef where jdwCustomerTlrdRef.operation_spec= '+ customer_name +'";
Otherwise if you want to pass the parameter later in your code then do it this way.
String query = "FROM JdwCustomerTlrdRef jdwCustomerTlrdRef WHERE jdwCustomerTlrdRef.operation_spec = :customer_name"
then in your code you can pass the parameter this way.
query.setParameter("customer_name", theCustomerNameParameter);
I am trying to make "filter" search for all questions in my database. Now I get a exception telling me that I can't compare enum values with string. Is it because I don't use the fully qualified package name of wher the enum type is declared? If so, is it better ways than hard-coding the package name?
Exception Description: Error compiling the query [SELECT q FROM
Question q WHERE q.status = 'APPROVED'], line 1, column 40: invalid
enum equal expression, cannot compare enum value of type
[app.utility.Status} with a non enum value of type
[java.lang.String].
public List<Question> all(Status status, ViewOption viewOption) {
String jpql = "SELECT q FROM Question q ";
boolean isWhereClauseAdded = false;
if (status != Status.ALL) {
if (!isWhereClauseAdded) {
jpql += "WHERE ";
}
jpql += "q.status = '" + status + "'";
}
if (viewOption != ViewOption.ALL) {
if (!isWhereClauseAdded) {
jpql += "WHERE ";
}
// Check if 'AND' operator is needed.
if (status != Status.ALL) {
jpql += " AND ";
}
switch (viewOption) {
case ONLY_IMAGES:
jpql += "q.image != ''";
break;
case NO_IMAGES:
jpql += "q.image = '' ";
break;
}
}
TypedQuery<Question> query = entityManager.createQuery(jpql,
Question.class);
return query.getResultList();
}
The right thing to do would be to use a query parameter:
String jpql = "select ... where q.status = :status";
Query query = em.createQuery(jpql).setParameter("status", status);
Rather than creating your query dynamically be concatenating query parts, you should also use the Criteria API, which has been designed with this goal in mind.
Can you try changing:
jpql += "q.status = '" + status + "'";
To:
jpql += "q.status = app.utility.Status." + status;