I would like to do a check in my PostgreSQL database with Eclipse Link in a named query and return a boolean. However when I change my count statement (which returns a correct value) to a case statement I get a NoResultException. What is the problem?
Following a simplified example:
#NamedQuery(name = "User.isExistent",
query = "SELECT CASE WHEN COUNT(u) > 0 THEN true ELSE false END
FROM User u WHERE u.someField = :someField")
Usage
TypedQuery<Boolean> query = em.createNamedQuery("User.isExistent", Boolean.class);
query.setParameter("someField", "someFieldValue");
Boolean result = query.getSingleResult();
Related
I have the following named query:
#NamedQueries({
#NamedQuery(name ="Movies.findByTitle", query = "SELECT m FROM Movies m WHERE m.title = :title")
})
When I try to execute it as follows:
public List<T> findByTitle(String title) {
return getEntityManager().
createNamedQuery("Movies.findByTitle").
setParameter("findByTitle", title).
getResultList();
}
Then I get the following exception:
You have attempted to set a parameter value using a name of findByTitle that does not exist in the query string SELECT m FROM Movies m WHERE m.title = :title.
How is this caused and how can I solve it?
You need to set a correct parameter name.
You can see in your query the parameter is named "title" not "findByTitle".
setParameter("findByTitle", title) change this to setParameter("title", title)
But updation works with below code snippet
Department department= departmentRepository.findOne(300L);
department.setName("rajiv");
departmentRepository.saveAndFlush(department);
but then this scenario being onetone mapping it could be a case where i would end up hitting 3 queries which include 2 select queries and one one update query .
To optimize the way i update it i'm trying to use this approach which is not getting updated thought executeUpdate() returns affected row as 1 .
There is a small mistake in your query.
You have used the = operator instead you should have used the like operator
You can also take help of #NamedNativeQueries
Example
DepartmentRepository.java
#Query(nativeQuery = true)
public List<Department> update(Long id);
Department.java
#SqlResultSetMapping(name="updateResult", columns = { #ColumnResult(name = "count")})
#NamedNativeQueries({
#NamedNativeQuery(
name = "Department.update",
query = "UPDATE departmemnt SET name like 'rajiv' WHERE id = ?",
resultSetMapping = "updateResult")
})
NativeQueries works more faster than normal Hibernate Queries
Yeah may this would help , in case of spring data i found a way to make it updatable and since they insist to use #transactional and extend the functionality of jparepository and now it hits only one line of statement
#Modifying(clearAutomatically = true)
#Transactional(readOnly=false)
#Query("update Department d set d.name =:name where d.id=:id")
int update(#Param("name")String name,#Param("id")Long id);
in case if i choose to for nativeQuery
#Modifying(clearAutomatically = true)
#Transactional(readOnly=false)
#Query(value="update Department d set d.name =:name where d.id=:id",nativeQuery=true)
int update(#Param("name")String name,#Param("id")Long id);
I'm trying to define a criteria query with a function in select and in where statement.
The SQL query is:
select s.*, contr_topay(s.id) as rest
from spedizionestd s
where contr_topay(s.id) >0
... other conditions
... optional order by
contr_topay is the procedure in the database (Postgresql). I've defined a NamedStoredProcedure:
#NamedStoredProcedureQuery(
name = "MovimentoContrassegno.contr_topay",
procedureName = "contr_topay",
parameters = {
#StoredProcedureParameter(mode = ParameterMode.IN, queryParameter = "idsped", type = Long.class, optional = false),
#StoredProcedureParameter(mode = ParameterMode.OUT, queryParameter="importo", type=Double.class, optional = false),
}
)
and called it with success:
StoredProcedureQuery query = this.em.createNamedStoredProcedureQuery("MovimentoContrassegno.contr_dapagare");
query.setParameter("idsped", myid);
query.execute();
return (Double) query.getOutputParameterValue(2);
Now, how can I put the procedure in the select clause and in the where condition inside a criteria query?
NB: i need criteria query because I build dynamic query with additional where conditions and "order by" choised by the user at runtime
(I'm using eclipselink 2.6.0)
I am struggling with JPQL dynamic where condition. I tried searching the syntax for the same but coluldn't find one.
in my case if user is passing the name parameter then the select query should be
select * from user where name = 'sanjay'
if user is not passing name parameter then select query should be
select * from user
Below is my jpql query format which fails when name parameter is not passed.
entity_manager.createQuery("select u from user u where u.name = :name").setParameter("name",params[:name]).getResultList()
How can i update above JPQL query to support both the cases i.e when the name parameter is passed and when the name parameter is not passed ??
This is not possible in JPQL. You even cannot do something like
createQuery("select u from user u where u.name = :name OR :name IS NULL")
It is not possible. That simple. Use two queries or use the Criteria API.
This is the answer I get when I tries to do like you it is working with some modification.
In my case I had the problem that my optional parameter was a List<String> and the solution was the following:
#Query(value = "SELECT *
FROM ...
WHERE (COLUMN_X IN :categories OR COALESCE(:categories, null) IS NULL)"
, nativeQuery = true)
List<Archive> findByCustomCriteria1(#Param("categories") List<String> categories);
This way:
If the parameter has one or more values it is selected by the left side of the OR operator
If the parameter categories is null, meaning that i have to select all values for COLUMN_X, will always return TRUE by the right side of the OR operator
Why COALESCE and why a null value inside of it?
Let's explore the WHERE clause in all conditions:
Case 1: categories = null
(COLUMN_X IN null OR COALESCE(null, null) IS NULL)
The left part of the OR will return false, while the right part of the OR will always return true, in fact COALESCE will return the first non-null value if present and returns null if all arguments are null.
Case 2: categories = ()
(COLUMN_X IN null OR COALESCE(null, null) IS NULL)
JPA will automatically identify an empty list as a null value, hence same result of Case 1.
Case 3: categories = ('ONE_VALUE')
(COLUMN_X IN ('ONE_VALUE') OR COALESCE('ONE_VALUE', null) IS NULL)
The left part of the OR will return true only for those values for which COLUMN_X = 'ONE_VALUE' while the right part of the OR will never return true, because it is equals to 'ONE_VALUE' IS NULL (that is false).
Why the null as second parameter? Well, that's because COALESCE needs at least two parameters.
Case 4: categories = ('ONE_VALUE', 'TWO_VALUE')
(COLUMN_X IN ('ONE_VALUE', 'TWO_VALUE') OR COALESCE('ONE_VALUE', 'TWO_VALUE', null) IS NULL)
As in Case 3, the left part of the OR operator will select only the rows for which COLUMN_X is equale to 'ONE_VALUE' or 'TWO_VALUE'.
Is it possible to write JPQL query like following:
select count(*) > 0 from Scenario scen where scen.name = :name
that would return true/false boolean values depending of whether entity filling criteria exists or not?
I would like to use the query this way:
boolean exists = entityManager.createQuery(query,Boolean.class).setParameter("name",name).getSingleResult();
The query from my example just isn't syntactically correct (parse error), but is there any correct way of doing checks like that in JPQL, that would return boolean value, or is it only possible in Java code?
Yes, it is possible with following:
select case when (count(scen) > 0) then true else false end
from Scenario scen where scen.name = :name
What about just:
select count(scen) > 0
from Scenario scen where scen.name = :name
I was having the same problem, then I updated my hibernate to 4.3.11.Final and now it's working.
I had success with:
#Query(nativeQuery = true, value = "select if(count(name) > 0, 'true', 'false') from Scenario scene where scene.name = :name")
Boolean nameExists(#Param("name") String name);
NOTE: I'm using MySQL with MariaDB
Just use
#Query("select count(scen) > 0 from Scenario scen where scen.name = :name")