JPA could not locate named parameter - java

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"

Related

How to format Date in JPA query

I have a SpringBoot application where I use Repository class to query my Oracle DB table.
Here is how the query and associated function are defined :
#Query( value =" SELECT status "+
" FROM tb1 " +
" WHERE " +
" to_date(cob_Date,'dd-MON-yy') = to_date(:cobDate,'yyyy-mm-dd') " +
" AND business_Day ='BD3' " +
" AND intra_day ='INTRA_06' " +
" AND datasource_name =:datasource" +
" AND upper(status) = 'COMPLETED' " +
" AND frequency = 'MONTHLY' " +
" AND processed = 'Y' " +
" ORDER BY create_date desc FETCH FIRST 1 rows only"
, nativeQuery=true)
List<String> getImpalaJobStatus(#Param("intraDay") String intraDay,
#Param("businessDay") String businessDay,
#Param("cobDate") LocalDate cobDate,
#Param("datasource") String datasource);
If I run this query in SQL developer then I am getting my results back, however if I run it from my SpringBoot Application it returns nothing.
I suspect I am doing something wrong with the Date field "COB_DATE" and this clause under WHERE:
" to_date(cob_Date,'dd-MON-yy') = to_date(:cobDate,'yyyy-mm-dd') " +
I tried it as :
" cob_Date =:cobDate "
but it didn't work either.
That cobDate is being declared as a LocalDate in the method signature implies that you already have that value in date format. If so, then the call to to_date() in the query is not needed. Try binding the LocalDate value directly:
#Query( value =" SELECT status "+
" FROM tb1 " +
" WHERE " +
" to_date(cob_Date,'dd-MON-yy') = :cobDate " +
" AND business_Day ='BD3' " +
" AND intra_day ='INTRA_06' " +
" AND datasource_name =:datasource" +
" AND upper(status) = 'COMPLETED' " +
" AND frequency = 'MONTHLY' " +
" AND processed = 'Y' " +
" ORDER BY create_date desc FETCH FIRST 1 rows only"
, nativeQuery=true)
List<String> getImpalaJobStatus(#Param("intraDay") String intraDay,
#Param("businessDay") String businessDay,
#Param("cobDate") LocalDate cobDate,
#Param("datasource") String datasource);
Note that your Oracle JBDC driver should know how to marshall the LocalDate value to the database such that the query works.

Hibernate Query, how to use like or = on where clause depend on value passed

I have the following code and query :
String kodeCustomer, kodeDropship, kodeSales, kodePengirim;
kodeCustomer = kodeCustomerTextField.getText().trim();
kodeDropship = kodeDropshipTextField.getText().trim();
kodeSales = kodeSalesTextField.getText().trim();
kodePengirim = pengirimTextField.getText().trim();
... some other code ...
record = session.createQuery("from PenjualanTableDb where"
+ " dtanggalpenjualan >= :dawalParm"
+ " and dtanggalpenjualan < :dakhirParm"
+ " and coalesce(ckodecustomer,'') like :custParm"
+ " and coalesce(ckodedropship,'') like :dropshipParm"
+ " and coalesce(ckodesalesperson,'') like :salesParm"
+ " and coalesce(ckodepengirim,'') like :pengirimParm")
.setParameter("dawalParm", tanggalMulaiTrx)
.setParameter("dakhirParm", tanggalAkhirTrx)
.setParameter("custParm", kodeCustomer + "%")
.setParameter("dropshipParm", kodeDropship + "%")
.setParameter("salesParm", kodeSales + "%")
.setParameter("pengirimParm", kodePengirim + "%")
.list();
how to modify the query so it can give the correct output based on user input.
if textfield empty then the query using like, but if textfield not empty then query using =
Is there an easy way to handle that?
Thanks in advance
I think you should construct the hql query (including parameters) dynamically according to the parameters present instead of using "a like%".
record = session.createQuery("from PenjualanTableDb where"
+ " dtanggalpenjualan >= :dawalParm"
+ " and dtanggalpenjualan < :dakhirParm"
+ " and coalesce(ckodecustomer,'') like '%:custParm%'"
+ " and coalesce(ckodedropship,'') like '%:dropshipParm%'"
+ " and coalesce(ckodesalesperson,'') like '%:salesParm%'"
+ " and coalesce(ckodepengirim,'') like '%:pengirimParm%'")
.setParameter("dawalParm", tanggalMulaiTrx)
.setParameter("dakhirParm", tanggalAkhirTrx)
.setParameter("custParm", kodeCustomer)
.setParameter("dropshipParm", kodeDropship)
.setParameter("salesParm", kodeSales)
.setParameter("pengirimParm", kodePengirim)
.list();

how to pass positional parameters to createnativequery jpa java

I have the following SQL query in my j2ee web app that I am unable to get to work, as-is. The named parameters sourceSystem and sourceClientId do not appear to get passed to the query, and therefore it does not return any records. I added a watch to the Query object querySingleView and it maintained a value of null as the debugger ran through the code. I also inserted a System.out.println statement just under the method declaration and confirmed that the correct values sourceSystem and sourceClientId are being passed to the method signature. I am using NetBeans 8.0, JPA 2.1, running on a JBoss EAP 6.21 server. I have multiple Entities mapped to several tables in an Oracle database.
Here is the query (I should note that the items in the query follow a schema.table.column format - not sure if that is part of the problem, but it does work in one test, see my comment and sample below the main query below):
public List<String> searchSingleView (String sourceSystem, String sourceClientId) {
//Change the underscore character in the source system value to a dash, and make it uppercase. This is what single view accepts
if (!sourceSystem.equals("")) {
sourceSystemSingleView = sourceSystem.replace('_', '-').toUpperCase();
}
String sqlSingleViewQuery = "SELECT DISTINCT " +
"MDMCUST_ORS.C_BO_CONTRACT.LAST_ROWID_SYSTEM AS POLICY_SYSTEM, " +
"MDMCUST_ORS.C_BO_CONTRACT.SRC_POLICY_ID AS POLICY_ID, " +
"MDMCUST_ORS.C_BO_CONTRACT.ISSUE_DT, " +
"MDMCUST_ORS.C_BO_PARTY_XREF.SRC_CLIENT_ID AS SRC_CLIENT_ID, " +
"MDMCUST_ORS.C_BO_PARTY_XREF.PERS_FULL_NAME_TXT, " +
"MDMCUST_ORS.C_BO_PARTY_XREF.ORG_LEGAL_NAME_TXT, " +
"MDMCUST_ORS.C_BO_PARTY_XREF.ORG_LEGAL_SFX_TXT, " +
"MDMCUST_ORS.C_BO_PARTY_XREF.ORG_NAME_TXT, " +
"MDMCUST_ORS.C_BO_PARTY_XREF.SIN_BIN_TEXT, " +
"MDMCUST_ORS.C_BO_PARTY_XREF.PERS_BIRTH_DT, " +
"MDMCUST_ORS.C_LU_CODES.CODE_DESCR_EN AS ADDRESS_PURPOSE_CD, " +
"MDMCUST_ORS.C_BO_PARTY_POSTAL_ADDR.COMPLETE_ADDRESS_TXT, " +
"MDMCUST_ORS.C_BO_PARTY_POSTAL_ADDR.CITY_NAME, " +
"MDMCUST_ORS.C_BO_PARTY_POSTAL_ADDR.COUNTRY_NAME, " +
"MDMCUST_ORS.C_BO_PARTY_POSTAL_ADDR.POSTAL_CD, " +
"MDMCUST_ORS.C_BO_PARTY_POSTAL_ADDR.STATE_PROVINCE_NAME " +
"FROM MDMCUST_ORS.C_BO_PARTY_XREF " +
"LEFT JOIN MDMCUST_ORS.C_BO_PARTY_POSTAL_ADDR ON MDMCUST_ORS.C_BO_PARTY_POSTAL_ADDR.PARTY_ROWID = MDMCUST_ORS.C_BO_PARTY_XREF.ROWID_OBJECT " +
"LEFT JOIN MDMCUST_ORS.C_LU_CODES ON MDMCUST_ORS.C_BO_PARTY_POSTAL_ADDR.POSTAL_ADDR_PURPOSE_CD = MDMCUST_ORS.C_LU_CODES.CODE " +
"LEFT JOIN MDMCUST_ORS.C_BO_PARTY_REL ON MDMCUST_ORS.C_BO_PARTY_XREF.ROWID_OBJECT = MDMCUST_ORS.C_BO_PARTY_REL.FROM_PARTY_ROWID " +
"LEFT JOIN MDMCUST_ORS.C_BO_CONTRACT ON MDMCUST_ORS.C_BO_PARTY_REL.CONTRACT_ROWID = MDMCUST_ORS.C_BO_CONTRACT.ROWID_OBJECT " +
"WHERE MDMCUST_ORS.C_BO_CONTRACT.LAST_ROWID_SYSTEM = :sourceSystemSingleView " +
"AND MDMCUST_ORS.C_BO_PARTY_XREF.SRC_CLIENT_ID = :sourceClientId " +
"AND MDMCUST_ORS.C_BO_PARTY_POSTAL_ADDR.POSTAL_ADDR_PURPOSE_CD = '56|07' " +
"AND MDMCUST_ORS.C_BO_PARTY_POSTAL_ADDR.LAST_ROWID_SYSTEM = MDMCUST_ORS.C_BO_CONTRACT.LAST_ROWID_SYSTEM " +
"ORDER BY MDMCUST_ORS.C_BO_CONTRACT.LAST_ROWID_SYSTEM";
querySingleView = emSingleView.createQuery(sqlSingleViewQuery);
querySingleView.setParameter("sourceSystemSingleView", sourceSystemSingleView);
querySingleView.setParameter("sourceClientId", sourceClientId);
querySingleViewResult = (List<String>) querySingleView.getResultList();
return querySingleViewResult;
}
}
However, if I put literal values in the SQL query in place of the positional parameters it works fine (without using the setParameter method).
WHERE MDMCUST_ORS.C_BO_CONTRACT.LAST_ROWID_SYSTEM = 'ADMIN' " +
"AND MDMCUST_ORS.C_BO_PARTY_XREF.SRC_CLIENT_ID = '0000001234' " +
I have looked online but haven't as yet found anything that seems to address this specific question. Any help would be greatly appreciated. Thank you!

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();

SQL: ten first contacts that I have received message from or sent to along with their latest sent message and time

I have a follow up to complicated mysql question that I recently asked: Show the ten first contacts that I have recieved message
Now I know that it is missing something, my last question was:
I want to create Sql statement that
show the ten first contacts that I
have recieved message from along with
their latest sent message and time.
The table columns is messageId,
message, fromProfileId, toProfileId,
timeStamp and table is called
messages. The database is Mysql and
Java is the language. But I want this
to happen in one single sql statement.
What's missing is that I want to show the message I've sent also, but it should be grouped with the messages that I've recieved from the user I've sent to:
ten first contacts that I have
received message from or sent to along
with their latest sent message and
time.
Little complicated to understand? Ok. think like this. the quoted first sql statement above only show messages that I reveived from. but what if I send a message? That message will never show up.
This is my code, but I failed to succed(look at where I marked the comment):
"SELECT M2.messageProfileId, profiles.profileMiniature, profiles.firstName, profiles.lastName, profiles.timeFormat, lastMessages.message, lastMessages.timeStamp " +
"FROM (" +
" SELECT IF(M1.fromProfileId = ?, M1.toProfileId, M1.fromProfileId) AS messageProfileId, " +
" max(M1.timeStamp) AS lastMessageTime " +
" FROM messages AS M1 " +
" WHERE M1.toProfileId = ? " +
" OR M1.fromProfileId = ? " +
" GROUP BY IF(M1.fromProfileId = ?, M1.toProfileId, M1.fromProfileId) " +
" ORDER BY max(M1.timeStamp) DESC " +
" LIMIT 10 " +
" ) AS M2 " +
"INNER JOIN messages AS lastMessages " +
"ON (" +
" lastMessages.timeStamp = M2.lastMessageTime " +
"AND lastMessages.fromProfileId = M2.messageProfileId" +//This to be like the if statements above, but how?
" )" +
"INNER JOIN profiles " +
"ON M2.messageProfileId = profiles.profileId ";
UPDATE:
All question marks in the above code will be replaced with a a same id, for example 27.
UPDATE:
You just have to solve one line now. Look at the commented line above. I dont know how to make if statement in where clause?
Ok figured it out myself
"SELECT M2.messageProfileId, profiles.profileMiniature, profiles.firstName, profiles.lastName, profiles.timeFormat, lastMessages.message, lastMessages.timeStamp " +
"FROM (" +
" SELECT IF(M1.fromProfileId = ?, M1.toProfileId, M1.fromProfileId) AS messageProfileId, " +
" max(M1.timeStamp) AS lastMessageTime " +
" FROM messages AS M1 " +
" WHERE (M1.toProfileId = ? " +
" OR M1.fromProfileId = ?) " +
" GROUP BY IF(M1.fromProfileId = ?, M1.toProfileId, M1.fromProfileId) " +
" ORDER BY max(M1.timeStamp) DESC " +
" LIMIT 10 " +
" ) AS M2 " +
"INNER JOIN messages AS lastMessages " +
"ON (" +
" lastMessages.timeStamp = M2.lastMessageTime " +
"AND (" +
" lastMessages.fromProfileId = M2.messageProfileId " +
"OR lastMessages.toProfileId = M2.messageProfileId " +
" )" +
" )" +
"INNER JOIN profiles " +
"ON M2.messageProfileId = profiles.profileId ";

Categories