SQL generated by Hibernate invalid for MS SQL - java

Hibernate (HQL) generated the following SQL for which I inserted the parameters:
select
sum(activity0_.calculated_work) as col_0_0_
, employee2_.id as col_1_0_
, projectele1_.id as col_2_0_
from
activity activity0_
inner join generic_object activity0_1_ on activity0_.id=activity0_1_.id
left outer join project_element projectele1_ on activity0_.project_element_id=projectele1_.id
left outer join employee employee2_ on activity0_.owner_id=employee2_.id
left outer join org_unit orgunit3_ on employee2_.org_unit_id=orgunit3_.id
where
activity0_1_.deleted=0 and
activity0_.client_id=22
group by
employee2_.id order by SUM(activity0_.calculated_work) DESC
Error message: Column 'project_element.id' is invalid in the select list because it is not contained in either an aggregate function or the GROUP BY clause.
I executed this SQL directly in the SQL Server Studio with the same result. I commented this line:
, projectele1_.id as col_2_0_
The SQL was then accepted by the SQL Server
The table project_element definitely has a column with the name id it is also referenced in the LEFT OUTER JOIN and there this column is not causing an error.
Removing the alias projectele1_ had no effect.
To me this looks like a really simple SQL statement. I cannot imagine what is wrong with it and the error message is not helping at all. Any ideas what could be wrong with the SQL?

Your SQL syntax is wrong.If you add projectele1_.id to group by clause it will work.Only aggregate functions work in select statement with group by clause.Or if you remove projectele1_.id from select it will work fine.

My mistake. I should have read the error message several times. projectele1_id is not in the group by clause. MS SQL does not allow to include such a column into the select list. This seems to be a consistency check.
Too bad though that the usage of HQL leads to such an exception in SQL Server but not in MySQL Server.

Related

Java SQLException SQL0901 and AS400 MCH1210 errors

I'm running a rather large query (~83k results) through my Java Application that is producing the following error:
java.sql.SQLException: [SQL0901] SQL system error. Cause . . . . . : An SQL system er
ror has occurred. The current SQL statement cannot be completed successfully. The error will not prevent other SQL statements from being processed. Previous messages may indicate that there is a problem with the SQL statement and SQL did not correctly diagnose the error. The previous message identifier was MCH1210. Internal error type 3002 has occurred. If precompiling, processing will not continue beyond this statement. Recovery: See the previous messages to determine if there is a problem with the SQL statement. To view the messages, use the DSPJOBLOG command if running interactively, or the WRKJOB command to view the output of a precompile. An application program receiving this return code may attempt further SQL statements. Correct any errors and try the request again.
From this page, it appears as though Error SQL0901 means I may have a Driver issue.
Digging into the MCH1210 error, yielded this StackOverflow question so I thought that maybe I would have the same issue, however there are a few differences.
When I attempt to run my query in the System iNavigator, it works just fine. When it runs in my application, I get the above error.
This is my query:
SELECT
DWVNDN, DWINVN, DWDTEI, DWRTPE, DWINAM, DWCHKN, DWJCDE
FROM HSDATA4.DWRECAP
WHERE DWDTEI > 20180901 AND (DWRTPE = 2 OR DWRTPE = 3) AND DWINVN IN
(SELECT DW.DWINVN
FROM HSDATA4.DWRECAP DW
INNER JOIN HSDATA4.FXVNDCP FX ON DW.DWVNDN = FX.FXVNDN
WHERE DW.DWRTPE = 1 AND DW.DWDTEI BETWEEN 20180904 AND 20190904)
ORDER BY DWDTEI ASC, DWVNDN ASC;
I should note that when changing the inner query from SELECT ... to SELECT COUNT(*) to get a tally of records coming back, the returned value is 83314, so the main query is using over 83k parameters.
I was originally going to ignore it because I was getting results, however it appears that some of the results end up getting cut off so I don't know how to proceed.
Also, if you hate the column names in the database...so do I. It wasn't my choice...
Doesn't the inner join give you everything that you need?
SELECT
DW.DWVNDN, DW.DWINVN, DW.DWDTEI, DW.DWRTPE, DW.DWINAM, DW.DWCHKN, DW.DWJCDE
FROM HSDATA4.DWRECAP DW
INNER JOIN HSDATA4.FXVNDCP FX ON DW.DWVNDN = FX.FXVNDN
WHERE DW.DWRTPE = 1 AND DW.DWDTEI BETWEEN 20180904 AND 20190904
AND DW.DWDTEI > 20180901 AND DW.DWRTPE IN (2,3)
ORDER BY DW.DWDTEI ASC, DW.DWVNDN ASC;
How about an outer join
SELECT
DW2.DWVNDN, DW2.DWINVN, DW2.DWDTEI, DW2.DWRTPE, DW2.DWINAM, DW2.DWCHKN, DW2.DWJCDE
FROM
(( HSDATA4.DWRECAP DW INNER JOIN HSDATA4.FXVNDCP FX
ON DW.DWVNDN = FX.FXVNDN AND DW.DWRTPE = 1
AND DW.DWDTEI BETWEEN 20180904 AND 20190904)
LEFT OUTER JOIN HSDATA4.DWRECAP DW2
ON DW.DWVNDN = DW2.DWVNDN
AND DW2.DWDTEI > 20180901 AND DW2.DWRTPE in (2,3))
The inner join selects the initial invoice type of 1 between your valid date ranges and the left outer join selects matching invoice numbers where there was a modification

How to write this query with hibernate using mysql DB

I am trying to select one row from all 3 tables. The tables have the same structure, 4 columns, "code", "airportname", "latitude", "longitude".
The query I am trying to write is:
select
finnairroute.code,finnairroute.airportname,finnairroute.latitude,finnairroute.longitude,lhroute.airportname,lhroute.latitude,lhroute.longitude,sasroute.code,sasroute.airportname,sasroute.latitude,sasroute.longitude
FROM frs.sasroute, frs.finnairroute,frs.lhroute where
sasroute.code="BER" or finnairroute.code ="BER" or lhroute.code
="BER";
Tested with Mysql workbench and I got this result:
How should I write the query in order to get one single row that has all the info for "BER"?
Many thanks!
You can try something like this:
SELECT finnairroute.*,lhroute.*,sasroute.* FROM DUAL
LEFT OUTER JOIN finnairroute ON (finnairroute.code='BER')
LEFT OUTER JOIN lhroute ON (lhroute.code='BER')
LEFT OUTER JOIN sasroute ON (sasroute.code='BER')
The thing is that you will always get one row, even if the code is in none of the table. You need to test whether finnairroute.code, lhroute.code and sasroute.code are null or not.
Another way to approach the problem:
SELECT 'finnair' as company,code,airportname,latitude,longitude FROM finnairroute WHERE code='BER'
UNION SELECT 'lh' as company,code,airportname,latitude,longitude FROM lhroute WHERE code='BER'
UNION SELECT 'sas' as company,code,airportname,latitude,longitude FROM sasroute WHERE code='BER'
This gives you between zero and three rows, depending on what tables contain the code 'BER'. An additional column, 'company' tels you which table contains each row.

Delete from table on same select same table mariadb using jpa

I need delete from table on operation of same table .JPA query is
DELETE FROM com.model.ElectricityLedgerEntity a
Where a.elLedgerid IN
(SELECT P.elLedgerid FROM
(SELECT MAX(b.elLedgerid)
FROM com.model.ElectricityLedgerEntity b
WHERE b.accountId='24' and b.ledgerType='Electricity Ledger' and b.postType='ARREARS') P );
I got this error:
with root cause org.hibernate.hql.ast.QuerySyntaxException: unexpected
token: ( near line 1, column 109 [DELETE FROM
com.bcits.bfm.model.ElectricityLedgerEntity a Where a.elLedgerid IN (
SELECT P.elLedgerid FROM ( SELECT MAX(b.elLedgerid) FROM
com.bcits.ElectricityLedgerEntity b WHERE b.accountId='24'
and b.ledgerType='Electricity Ledger' and b.postType='ARREARS') P ) ]
at
org.hibernate.hql.ast.QuerySyntaxException.convert(QuerySyntaxException.java:54)
at
org.hibernate.hql.ast.QuerySyntaxException.convert(QuerySyntaxException.java:47)
at
org.hibernate.hql.ast.ErrorCounter.throwQueryException(ErrorCounter.java:82)
at
org.hibernate.hql.ast.QueryTranslatorImpl.parse(QueryTranslatorImpl.java:284)
Same query is running on mysql terminal ,but this is not working with jpa .Can any one tell me how i can write this query using jpa .
I don't understand why do you use Pbefore the last parenthesis...
The following code is not enough ?
DELETE FROM com.model.ElectricityLedgerEntity a
Where a.elLedgerid IN
(SELECT MAX(b.elLedgerid)
FROM com.model.ElectricityLedgerEntity b
WHERE b.accountId='24' and b.ledgerType='Electricity Ledger' and
b.postType='ARREARS')
Edit for bypassing mysql subquery limitations :
The new error java.sql.SQLException: You can't specify target table 'LEDGER' for update in FROM clause
is known in mysql when you use it with JPA. It's one MySQL limitation.
A recent stackoverflow question about it
In brief, you cannot "directly" updated/deleted a table that you query in a select clause
Now I understand why your original query did multiple subqueries seemingly not necessary (while it was useful for mysql) and had a "special" syntax.
I don't know tricks to solve this problem in JPA (I don't use the MySQL DBMS for a long time now).
At your place, I would do two queries. The first where you select the expected max elLedgerid and the second where you could delete line(s) with the id retrieved in the previous query.
You should not have performance issues if your sql model is well designed, the sql indexes well placed and the time to access to the database is correct.
You cannot do this in a single query with Hibernate. If you want to delete the max row(s) with Hibernate you will have to do so in two steps. First, you can find the max entry, then you can delete using that value in the WHERE clause.
But the query you wrote should actually run as a raw MySQL query. So why don't you try executing that query as a raw query:
String sql = "DELETE FROM com.model.ElectricityLedgerEntity a " +
"WHERE a.elLedgerid IN (SELECT P.elLedgerid FROM " +
"(SELECT MAX(b.elLedgerid) FROM com.model.ElectricityLedgerEntity b " +
"WHERE b.accountId = :account_id AND b.ledgerType = :ledger_type AND " +
" b.postType = :post_type) P );";
Query query = session.createSQLQuery(sql);
query.setParameter("account_id", "24");
query.setParameter("ledger_type", "Electricity Ledger");
query.setParameter("post_type", "ARREARS");
Just want to extend existing answer:
In brief, you cannot "directly" updated/deleted a table that you query in a select clause
This was lifted with starting from MariaDB 10.3.1:
Same Source and Target Table
Until MariaDB 10.3.1, deleting from a table with the same source and target was not possible. From MariaDB 10.3.1, this is now possible. For example:
DELETE FROM t1 WHERE c1 IN (SELECT b.c1 FROM t1 b WHERE b.c2=0);

MySql query syntax error from hibernate

the following query is not getting executed. it is throwing error. i am not able to identify the error. its is generated by hibenate.
Driver class org.gjt.mm.mysql.Driver, dialect:org.hibernate.dialect.MySQLDialect
please help me waht is the error.
jdbc:mysql://localhost:3306/mydb
select this_.Student_Id as Student1_8_0_, this_.student Name as student2_8_0_,
this_.address as address8_0_, this_.Father Name as Father4_8_0_,
this_.Mother Name as Mother5_8_0_, this_.Primary Contact No as Primary6_8_0_,
this_.Secondary Contact No as Secondary7_8_0_, this_.Occupation as Occupation8_0_,
this_.Mode_Id as Mode9_8_0_, this_.Class_Id as Class10_8_0_,
this_.Route_No as Route11_8_0_
from Tbl_Student this_
if i run as select * from Tbl_Student like this it is working fine.
You should use back-ticks to enclose column names separated with spaces:
`this_`.`Father Name`, ..
What is that code? Is it your HQL statement or is it the SQL statement generated by Hibernate?
If it is your HQL statement:
You have to use the names of the properties, i. e. the Java member names as column names.
If it is the SQL statement generated by Hibernate:
There is probably an error in your mapping, and you used a space instead of an underscore in Father_Name, Mother_Name, Primary_Contact_No and Secondary_Contact_No.

Execute left join query in JPA

I have two tables, one for party and one for scorecard template mapping. The scorecard template mapping table has a foreign key back to the party (on id). I want to find a list of all of the parties that have scorecard template mapping details.
But I get an error which says :
java.lang.IllegalArgumentException:
org.hibernate.hql.internal.ast.QuerySyntaxException: unexpected token:
on near line 1, column 172 [select new
ScorecardTemplateMapping(p,temMap.scoTemplate,temMap.wrkFlwTemplate)
from com.kpisoft.common.web.domain.Party p left outer join
ScorecardTemplateMapping temMap on temMap.organization.id=p.id and
temMap.gradeType.id=:gradeType where
p.organization.organizationTypeId=:orgType and p.clientId=:clientId
order by p.organization.name]
This is my query:
Query q = entityManager.createQuery("select new
ScorecardTemplateMapping(p,temMap.scoTemplate,temMap.wrkFlwTemplate)
from Party p left outer join ScorecardTemplateMapping temMap on
temMap.organization.id=p.id and temMap.gradeType.id=:gradeType where
p.organization.organizationTypeId=:orgType and p.clientId=:clientId
order by p.organization.name");
I have no idea why this isn't working. Please help!
Error message about syntax error is quite clear:
unexpected token: on
There is no support to make join with ON [conditional] in JPQL (ON is not reserved word). How joins are made in JPQL, is told for example here. It boils down to that you have to present join condition in where clause.

Categories