Issue when adding NULLS LAST - java

When adding "NULLS LAST" on the following query I'm getting the exception below:
Caused by: com.microsoft.sqlserver.jdbc.SQLServerException: The value is not set for the parameter number 11.
If I remove the NULLS LAST everything works fine
If I remove the CASE WHEN code and order by just one specific column it works with the NULLS LAST, but I need all the columns on the CASE WHEN.
#Query("SELECT c FROM ClassSpecificationTableEntity c"
+ " LEFT JOIN c.owner o "
+ " LEFT JOIN c.domain d "
+ "WHERE ISNULL(c.classStructure.classification.description, '') LIKE :SEARCH "
+ " OR ISNULL(c.classStructure.description, '') LIKE :SEARCH "
+ " OR ISNULL(d.description, '') LIKE :SEARCH "
+ " OR ISNULL(o.description, '') LIKE :SEARCH "
+ " OR ISNULL(c.measurementUnit, '') LIKE :SEARCH "
+ " OR ISNULL(c.defaultValue, '') LIKE :SEARCH "
+ " OR ISNULL(c.dataType, '') LIKE :SEARCH "
+ " OR ISNULL(c.tooltip, '') LIKE :SEARCH "
+ " ORDER BY "
+ " CASE :ORDERBY" +
" WHEN 0 THEN c.classStructure.classification.description " +
" WHEN 1 THEN c.assetAttribId " +
" WHEN 2 THEN c.dataType " +
" WHEN 3 THEN c.measurementUnit " +
" WHEN 4 THEN c.domain.description " +
" WHEN 5 THEN c.owner.description " +
" WHEN 6 THEN c.defaultValue " +
" WHEN 7 THEN c.tooltip " +
" END DESC NULLS LAST"
)
Page<ClassSpecificationTableEntity> findByLikeSearchDESC(#Param(value="SEARCH") final String searchCrit, final Pageable pageable, #Param(value="ORDERBY") final String orderBy);

There is no NULLS LAST syntax is T-SQL.
If you want to order NULL values last the common way is to use a CASE expression or IIF:
--CASE Expression
CASE WHEN {expression} IS NULL THEN 1 ELSE 0 END
--IIF funciton (which is actually a shorthand CASE expression)
IIF({Expression} IS NULL, 1, 0)
If you have a complicated expression, that you want to order the NULL values last for, and then the expression, and that expression does not appear in the SELECT (so cannot be referenced by its Alias), then you can move the expression to the FROM, to avoid typing the expression multiple times:
FROM ...
JOIN ...
LEFT JOIN ...
...
CROSS APPLY (VALUES({Expression}))V(Alias)
WHERE ...
ORDER BY IIF(V.Alias IS NULL,1,0),
V.Alias

Related

JPA : Use of list in where clause and Case statement together - Is there a way to loop through?

I am using JPA-Hibernate in our application and I am working with a query like :
#Query(
value = "ReportDTO(report) FROM Report report " +
"JOIN p.clientFile cf " +
"JOIN cf.client cl " +
"WHERE report.active = TRUE " +
"AND :companyKey = CASE WHEN report.companyKey IS NOT NULL " +
"THEN report.companyKey " +
"ELSE cl.companyKey " +
"END " +
"ORDER BY report.publishedDate DESC",
countQuery = “..”
)
#NonNull
Page<TagReportDTO> findAll(#NonNull Pageable pageable, #Param("companyKey") String companyKey);
when the "companyKey" was a single value, it worked. Now, I need to change this findAll method to accept a list of company keys. So it should like like ( after the change) :
#NonNull
Page<TagReportDTO> findAll(#NonNull Pageable pageable, #Param("companyKeys") List<String> companyKeys);
Now I am getting hard time to accommodate the list of objects or companyKeys (instead of :companyKey) in the query where the the case statement will be applicable to each item in the list. Is there a way I can loop through ?
Did you try using IN operator? Like this:
"AND (CASE WHEN report.companyKey IS NOT NULL " +
"THEN report.companyKey " +
"ELSE cl.companyKey " +
"END) IN :companyKeys "

JPA top one row that match criteria

Using JPA and need help with the same.
Current query looks as below
#Query("SELECT o FROM orders o " +
"WHERE (o.type = 'type1'... " +
" ) " +
" OR (o.type = 'type2' ...... " +
" ) "
)
Page<Order> getOrders(Pageable pageable);
to the above now I have to add another "OR" condition (type3 as below) for which I need to get only 1 record that match criteria i.e limit one only for this new OR condition.
Need to limit 1 for below criteria only
" OR (o.type = 'type3' ...... " +
" limit 1) "
how can I do that in JPA?

Could not locate named parameter

I am not able to understand why the hibernate is not finding the parameter "setor" of the query below.
hql.append("select top :limite * from MA3OCORT oco,MA4DETOT ocodA " +
" where MA4IDOCO=ma3idoco " +
" and ocodA.MA4IDODE in (select max(ocodB.MA4IDODE) from MA4DETOT ocodB where ocodA.MA4IDOCO=ocodB.MA4IDOCO and ocodB.MA4IDSIT=:situacao)" +
" and (oco.MA3DSSOL like :solicitante or :solicitante is null)" +
" and (ocodA.MA4DTDET between :datai and :dataf or :dataf is null)" +
" and ocodA.MA4IDSET = :setor" +
"order by ocodA.MA4DTDET desc");
return em.createNativeQuery(hql.toString(), OcorrenciaDetalhe.class)
.setParameter("situacao", situacao)
.setParameter("solicitante", "%" + solicitanteFiltro + "%")
.setParameter("datai", dataRespostaFiltro1)
.setParameter("dataf", dataRespostaFiltro2)
.setParameter("setor", usuarioLogado.getSetor().getId())
.setParameter("limite", limit).getResultList();
Because there is a syntax error in the select
this
" and ocodA.MA4IDSET = :setor" +
"order by ocodA.MA4DTDET desc");
becomes
' and ocodA.MA4IDSET = :setororder by ocodA.MA4DTDET desc'
You need to add a blank character after :setor or before order.
You have to make a space between sector and order by:
like that :
hql.append("select top :limite * from MA3OCORT oco,MA4DETOT ocodA " +
" where MA4IDOCO=ma3idoco " +
" and ocodA.MA4IDODE in (select max(ocodB.MA4IDODE) from MA4DETOT ocodB where ocodA.MA4IDOCO=ocodB.MA4IDOCO and ocodB.MA4IDSIT=:situacao)" +
" and (oco.MA3DSSOL like :solicitante or :solicitante is null)" +
" and (ocodA.MA4DTDET between :datai and :dataf or :dataf is null)" +
" and ocodA.MA4IDSET = :setor" +
" order by ocodA.MA4DTDET desc");
return em.createNativeQuery(hql.toString(), OcorrenciaDetalhe.class)
.setParameter("situacao", situacao)
.setParameter("solicitante", "%" + solicitanteFiltro + "%")
.setParameter("datai", dataRespostaFiltro1)
.setParameter("dataf", dataRespostaFiltro2)
.setParameter("setor", usuarioLogado.getSetor().getId())
.setParameter("limite", limit).getResultList();

how to remove node itself in NOT logical cypher query?

I have this code in my method:
"match (n:" + query.getLabel() + " {" + propertiesGenerator(query.getNodeProperties()) + "}) ,(r:" + query.getLabel() + ")" +
"where NOT (n)-[:" + query.getRelation() + "{" + propertiesGenerator(query.getRelationProperties()) + "}]->(r)" +
"return r"
that it is equal to this cypher query in neo4j:
MATCH (a:Person {name:"salar"}),(r:Person)
WHERE NOT (a)-[:PARENT_OF {age:"20"}]->(r)
RETURN r
when i excute it , it return "a" node itself. in other words "a" dont have relation with itself.I dont want to return itself. how can i remove that?

JPA could not locate named parameter

I keep getting the following error: "could not locate named parameter [articleCommentId]" but it doesn't make sense to me because to me the named parameter is very much in place.
public ArticleCommentForDisplay getCommentByArticleCommentId(BigInteger articleCommentId) {
String queryString = "select c.article_comment_id, "
+ " c.article_id, "
+ " c.parent_comment_id, "
+ " p.nickname, "
+ " c.title, "
+ " c.comment, "
+ " c.person_id, "
+ " c.confirmed_user, "
+ " c.comment_depth, "
+ " c.moderation_rank, "
+ " c.moderation_reason, "
+ " c.hide, "
+ " c.hide_reason, "
+ " c.session_id, "
+ " c.confirmation_uuid, "
+ " c.created_timestamp, "
+ " c.created_by_id, "
+ " c.updated_timestamp, "
+ " c.updated_by_id, "
+ " c.update_action, "
+ " null as comment_path "
+ "from article_comment c "
+ " join person p "
+ " on p.person_id = c.person_id "
+ "where c.article_comment_id = :articleCommentId; ";
Query query = em.createNativeQuery(queryString, "ArticleCommentMap");
query.setParameter("articleCommentId", articleCommentId);
List <ArticleCommentForDisplay> articleComments = new ArrayList<>();
articleComments = query.getResultList();
ArticleCommentForDisplay theComment = articleComments.get(0);
return (theComment);
}
Here is an extract of the stack trace with the relevant error:
Caused by: java.lang.IllegalArgumentException: org.hibernate.QueryParameterException: could not locate named parameter [articleCommentId]
at org.hibernate.ejb.QueryImpl.setParameter(QueryImpl.java:379)
at org.hibernate.ejb.QueryImpl.setParameter(QueryImpl.java:72)
at com.extremelatitudesoftware.content.ArticleCommentFacade.getCommentByArticleCommentId(ArticleCommentFacade.java:293)
I bet it is due to the extra ; in your query string.
SQL/HQL does not need to be terminated by semicolon
The named parameters is not defined for native queries in JPA Specification.
Replace
where c.article_comment_id = :articleCommentId;
with
where c.article_comment_id = ?1;
....
query.setParameter(1, articleCommentId)
Mine was an extra ' in the sql query. Oh my gosh, kept looking until my eyes nearly pooooopped out `-)
So, ensure that you don't have anything "extra" in your query, make sure that your (, ", ' etc...have matching pairs, because the error message in that case is not relevant and has nothing to do with your named parameter! JPA is right as it could not locate it, but that's because something else in your query is messing up...
You can also use it like this
where c.article_comment_id = ?,
and c.any_other_field = ?;
....
query.setParameter(1, articleCommentId)
query.setParameter(2, anyOtherValue)
it will take it by sequence.
And you can also give numbers like
where c.article_comment_id = ?1,
and c.any_other_field = ?2;
....
query.setParameter(1, articleCommentId)
query.setParameter(2, anyOtherValue)
If you are using named parameter at end of your query the remove the ; from your query
In my case, I didn't add the extra space after the named parameter.
example:
+ "WHERE\n" + " s.something = 'SOME'\n" + "START WITH\n"
+ " s.country_type = :countryName" + "CONNECT BY\n"
changed to (notice the space after named parameter :countryName
+ "WHERE\n" + " s.something = 'SOME'\n" + "START WITH\n"
+ " s.country_type = :countryName " + "CONNECT BY\n"

Categories