JPQL unexpected AST node: around "coalesce" - java

JPQL got an error : threw
org.springframework.dao.InvalidDataAccessApiUsageException
(org.hibernate.hql.internal.ast.QuerySyntaxException: unexpected AST
node: ( near line 3, column 48 ) select invoiceBE from InvoiceBE
invoiceBE where invoiceBE.institutionId = ?1 and
coalesce(invoiceBE.paidActivity.date < ?2) and
invoiceBE.exportedActivity.date < ?3 order by
invoiceBE.vendorInvoiceNumber asc
Is there any error around "coalesce"?
I run the sql well in mysql database.
select
* from
ACQ_INVOICE invoice
where
invoice.institution_id=91475
and coalesce(invoice.`user_paid_date` < '2020-01-20', invoice.`paid_date` < '2020-01-20T16:45:40.786Z')
Thanks.

The coalesce expression looks all wrong.
I don't think back ticks to quote a property are allowed. That looks more like MySQL SQL syntax.
I'm also not completely sure if COALESCE may be used with boolean expressions.

Changed to
coalesce(invoice.user_paid_date, invoice.paid_date)< '2020-01-20'
And it worked.

Related

Error in Update JPA Query

I have a problem with this query when run is as follows
Query query = em.createQuery("UPDATE Equipo c JOIN c.histAsociados e SET e.horasTrabajadas = (CAST(c.horastd AS DECIMAL(18,2)) - (c.horastotales AS DECIMAL(18,2))) WHERE c.id=" + equipo.getId());
This is the exception that gets thrown when running
The SET identifier is missing from the UPDATE clause. [39, 39] The equal sign must be specified.[16, 38] The expression is invalid, which means it does not follow the JPQL grammar.[40, 43] The identification variable 'SET' cannot be a reserved word.[115, 115] The right parenthesis is missing from the sub-expression.[115, 115] The right parenthesis is missing from the sub-expression.[116, 126] The expression is invalid, which means it does not follow the JPQL grammar.[133, 151] The query contains a malformed ending.
Try something like this, putting it into a subquery, assuming that histAsociados is an entity inside Equipo entity:
Query query = em.createQuery("UPDATE Equipo c SET c.histAsociados WHERE c.histAsociados.id in(select Equipo.id from Equipo c1 LEFT JOIN c1.histAsociados e WHERE e.horasTrabajadas = (CAST(c1.horastd AS DECIMAL(18,2)) - (c1.horastotales AS DECIMAL(18,2))) AND c1.histAsociados.id = e.id) AND c.id=:id).setParameter("id", equipo.getId())
Also, could you please try putting some simple names to the attributes of entities. That increases readability.
According to the JPA specification, your syntax cannot be correct. The simplified form of the syntax for the UPDATEstatement can be stated as follows:
UPDATE <entity_name> <identification_variable> SET <identification_variable>.<state_field> = <value> WHERE <condition>
Applying this for your case it might look like:
"UPDATE HistAsociado?? e SET e.horasTrabajadas = (SELECT (CAST(c.horastd AS DECIMAL(18,2)) - CAST(c.horastotales AS DECIMAL(18,2))) AS DIFF FROM Equipo c WHERE c.id= " + equipo.getId())
In the above statement, I was guessing that HistAsociado could be an Entity name; otherwise you have to correct it!
The result of the subquery must also be a single value.
Warning: The modified statement would update all the records in the table as there is no WHERE condition is specified.
So, use this as a hint to solve the problem and don't use it before you have corrected the guessing and added the WHERE condition.
For more information and examples, you could read JPA update statement and this one too.

what is the equelent of sql query in hibernate

In SQL Server i am using this query
select *
from Unit c
ORDER BY CONVERT(INT, LEFT(name, PATINDEX('%[^0-9]%', name + 'z')-1)) desc;
I want this query to use in Hibernate. when I use this in Hibernate I got error
java.lang.IllegalArgumentException: org.hibernate.hql.ast.QuerySyntaxException:unexpected token: LEFT near line 1, column 122
[SELECT c FROM models.entities.UnitEntity c WHERE c.expSetId = :expSetId AND isWaitArea=:isWaitArea ORDER BY CONVERT(INT, LEFT(name, PATINDEX('%[^0-9]%', name + 'z')-1)) asc]
some of that is not in the hibernate dialect, you can change left with substring, convert with cast. and as for patindex i couldn't find the substitution. you either can add pathindex to the constructor of the dialect that you use
registerFunction( "patindex", new StandardSQLFunction("patindex") );
or create patindex() to a stored procedure.
then you can use something like this:
from Unit c order by cast(substring(name, 0, PATINDEX('%[^0-9]%', name + 'z')-1) as integer);
or you can use locate() instead of patindex(), but i think it doesn't support regular expression.
I am pretty sure that you can use SQL query with hibernate as well. When you create your hibernate session, you can use something like
session.createSQLQuery("Your Query Here")
Hope this helps.

Subquery - on clause column not visible

I facing with a strange situation with a sql query on mysql 5.1.41 environment on a Ubuntu machine.
The code follow
SELECT spedizione0_.idspedizione,
spedizione0_.*,
(
SELECT COUNT(n.idnegozio)
FROM negozio n
LEFT JOIN confezione c
ON n.idnegozio = c.idnegozio
AND c.idspedizione = spedizione0_.idspedizione
WHERE n.datainizio <= spedizione0_.dataspedizione
AND n.datafine >= spedizione0_.dataspedizione
OR c.idspedizione != 0
) AS formula5_
FROM orocashgenerico.spedizione spedizione0_
ORDER BY spedizione0_.dataspedizione DESC
In this case the error says : [Err] 1054 - Unknown column 'spedizione0_.idspedizione' in 'on clause'
The only way to run this query is to change the .. on n.idnegozio=c.idnegozio and c.idspedizione=spedizione0_.idspedizione into on n.idnegozio=c.idnegozio and c.idspedizione=12
The most strange things for me is: if i move the and condition to the where clause the query run correctly, of course the results is not what I excepted.
My question is where is the problem?
Is something related to the MySQL version?
It's because spedizione0_ is not found with the scope of your subquery. Try this one,
SELECT spedizione0_.idspedizione, // add additionl columns
COUNT(n.idnegozio) AS formula5_
FROM spedizione spedizione0_
LEFT JOIN confezione c
ON c.idspedizion = spedizione0_.idspedizione
LEFT JOIN negozio n
ON n.idnegozio = c.idnegozio
WHERE (
n.datainizio <= spedizione0_.dataspedizione AND
n.datafine >= spedizione0_.dataspedizione
)
OR c.idspedizione != 0
GROUP By spedizione0_.idspedizione
ORDER BY spedizione0_.dataspedizione DESC
as I can see, you are using the wrong syntax here. When you use a Left Outer join, you cannot mention more than one condition in ON clause.
In your case, you need to use one more Left join clause after that ON clause to join 3rd table which is giving error.

playframework use find with IN and a list of models

I've got a problem with the following code, written in play (1.2.4):
List<MSprache> sprachen = MSprache.find("active = ?", true).fetch();
List<MFieldDscr> textey = MFieldDscr.find("sprache IN", sprachen).fetch();
And if I execute a test, which tests this part of code, the following Error displays:
A java.lang.IllegalArgumentException has been caught, org.hibernate.hql.ast.QuerySyntaxException: unexpected token: null near line 1, column 48 [from models.Sprache.MFieldDscr where sprache IN]
I don't understand where the mistake is.
I'm not so sure about what you're trying to achieve,
but I think this is what you want:
String jpql = "FROM MFieldDescr fd WHERE fd.sprache "
+ "IN ( SELECT s FROM MSprache s WHERE s.active = ? ) ";
List<MFieldDscr> textey = MFieldDescr.find( jpql, true ).fetch();
This will find all the MFieldDescr entities which have a MSprache with active set to true.
The language used to query entities is JPQL by the way, in case you want to learn more about it.
Here are some useful links:
JPQL In Expressions
JPQL Subqueries

How can I use MySQL assign operator(:=) in hibernate native query?

I'm using Hibernate. I wrote some native query because I need to use sub select statement.
Query looks like this:
SELECT sub.rownum FROM
(SELECT k.`news_master_id` AS id, #row := #row + 1 AS rownum
FROM keyword_news_list k
JOIN (SELECT #row := 0) r
WHERE k.`keyword_news_id` = :kid
ORDER BY k.`news_master_id` ASC) AS sub
WHERE sub.id = :nid
When I run this query like this:
sessionFactory.getCurrentSession()
.createSQLQuery(query)
.setParameter("kid", kid)
.setParameter("nid", nid)
.uniqueResult();
This exception comes out:
org.hibernate.QueryException: Space is not allowed after parameter prefix ':' ....
This might because of := operator. I found some Hibernate issue about this. This issue is still open. Isn't there any solution for this problem?
Note that HHH-2697 is now fixed for Hibernate 4.1.3 You can now escape with backslash:
SELECT k.`news_master_id` AS id, #row \:= #row + 1 AS rownum
FROM keyword_news_list k
JOIN (SELECT #row \:= 0) r
WHERE k.`keyword_news_id` = :kid
ORDER BY k.`news_master_id` ASC
Another solution for those of us who can't make the jump to Hibernate 4.1.3.
Simply use /*'*/:=/*'*/ inside the query. Hibernate code treats everything between ' as a string (ignores it). MySQL on the other hand will ignore everything inside a blockquote and will evaluate the whole expression to an assignement operator.
I know it's quick and dirty, but it get's the job done without stored procedures, interceptors etc.
you can implement this is a slightly different way.. you need to replace the : operator with something else (say '|' char ) and in your interceptor replace the '|' with the : .
this way hibernate will not try to think the : is a param but will ignore it
For the interceptor logic you can refer to the hibernate manual
This has worked for me using MySQL 5.
remember, this replacing of : must be only done to ':=' and other MySQL specific requirments.. don't try to replace the : for the param-placeholders. (hibernate will not be able to identify the params then)
I prefer to include Spring JDBC and execute the query rather than fight against Hibernate interceptors.
in Hibernate exception on encountering mysql := operator Stanislav gave another option other than interceptor to solve this issue
If you keep your SQL-files away from Java code - try this piece of code. Played a lot to get the right number of escaping slashes:
String sqlPattern = FileUtils.readFile(this.getClass(), /sql/my_query.sql");
sqlPattern = sqlPattern.replaceAll(":=", "\\\\:=");
Query query = entityManager.createNativeQuery(sqlPattern);
I guess there should not be a space after = , the operator should be written as =: (without any spaces)

Categories