How can I JOIN multiple table columns in jpa and jpql - java

I'm new with JPA and JPQL. I'm trying to query a database grab rows from a table that contains mostly index's of the names contained in other tables.
This is the query in mysql that I'm trying to recreate:
SELECT COUNT(*) as PieceCount,
shifttimes.shiftid as ShiftId,
specienames.NameText as SpecieName,
gradenames.NameText as Grade,
DryerNum,
CreatedLocal
from sheets, shifttimes, specienames, gradenames
WHERE sheets.ShiftIndex = shifttimes.ShiftIndex AND
sheets.SpecieNameIndex = specienames.NameIndex AND
sheets.gradenameindex = gradenames.NameIndex AND
CreatedLocal >= '" . $begin . $StartGraveyard
' AND CreatedLocal < '" . $end . $StartGraveyard
GROUP BY ShiftId, SpecieName, Grade, DryerNum;
This is the query I have and as far as I've gotten:
SELECT COUNT(s.createdLocal),
g.nameText gName,
p.nameText pName
FROM Sheets s , GradeNames g , SpecieNames p
JOIN s.gradeNameIndex gIndex ,
JOIN s.specieNameIndex pIndex
WHERE gIndex = g.nameIndex AND
pIndex = p.nameIndex
GROUP BY gName , pName
This is the Java Glassfish error that I am receiving:
java.lang.IllegalArgumentException: An exception occurred while creating a query in EntityManager:
Exception Description: Syntax error parsing [SELECT COUNT(s.createdLocal), g.nameText, p.nameText FROM Sheets s , GradeNames g , SpecieNames p JOIN s.gradeNameIndex gIndex , JOIN s.specieNameIndex pIndex WHERE gIndex = g.nameIndex AND pIndex = p.nameIndex GROUP BY g.nameText , p.nameText].
[128, 128] The range variable declaration must be specified.

First off all, sorry, but this is not an answer but BIG comment...
You should better stop using this syntax FROM Sheets s , GradeNames g , SpecieNames p.
All tables you need should be properly JOINed by ON clause.
Any JOIN statement should have ON clause and should not have , any comma at the end.
If I understood your 2nd query correctly it must be something like:
SELECT COUNT(s.createdLocal),
g.nameText gName,
p.nameText pName
FROM Sheets s
JOIN GradeNames g
ON s.gradeNameIndex = g.nameIndex
JOIN SpecieNames p
ON s.specieNameIndex = p.nameIndex
GROUP BY gName , pName

Related

Inserting information from an Inner Join

I currently have 3 tables and an inner join containing all the tables.
SELECT I.idInvoice
, C.idCustomer
, C.FirstName
, C.Surname
, P.idProduct
, P.Quantity
, I.Date
, P.PName
, P.Price
, I.QuantityOrdered
FROM Invoice I
JOIN Customer C
on I.idCustomer = C.idCustomer
JOIN PRODUCT P
on I.idProduct = P.idProduct
LIMIT 0, 1000
I'm taking values from text labels, but the only problem is, I don't how to insert all the data into their respective tables. E.g. FirstName into Customer and Quantity into Product.

Incorrect Syntax near WHERE error in generated SQL

I am generating the below SQL. From my code I am using a where condition list to collect all the Where logic and insert it after the Join logic is set-up. However, I am getting a very generic syntax error and I can't figure out why. I am pretty sure the logic is properly organized however, when inserting the where statement it throws the syntax error
Incorrect Syntax near WHERE
The {h-schema} are just generated database and table names.
The code:
SELECT count(*) AS ID
FROM (
SELECT 'PREAPPROVAL' AS type, pa.id AS id FROM {h-schema}preapproval AS pa
LEFT JOIN {h-schema}risk_limit AS lim ON pa.limit_id = lim.id
LEFT JOIN {h-schema}desk AS d ON lim.desk_enterprise_id = d.enterprise_id AND CAST(pa.creation_date_time AS date) BETWEEN d.start_date AND d.end_date
WHERE pa.status = 'APPROVED' AND pd.end_date = NULL <-------------------------SYNTAX ERR HERE
OR pa.status = 'DECLINED' AND pa.completion_date_time > '2021-01-28 13:02:13'
OR pa.status = 'IN_PROGRESS'
OR pa.creation_date_time > '2021-01-28 13:02:13'
AND COALESCE(lim.policy_enterprise_id, d.policy_enterprise_id) IN (6)
UNION
SELECT 'BREACH' AS type, br.id AS id FROM {h-schema}breach AS br
LEFT JOIN {h-schema}risk_limit AS lim ON br.limit_id = lim.id
LEFT JOIN {h-schema}desk AS d ON lim.desk_enterprise_id = d.enterprise_id
AND br.reporting_date BETWEEN d.start_date AND d.end_date
LEFT JOIN {h-schema}valid_breach_recommendation AS vbr_approve ON vbr_approve.id = (SELECT TOP(1) id FROM {h-schema}valid_breach_recommendation
WHERE breach_id = br.id AND outcome = 'APPROVE'
ORDER BY creation_date_time DESC, id DESC)
LEFT JOIN {h-schema}valid_breach_decision AS vbd
ON vbd.id = (SELECT TOP(1) id FROM {h-schema}valid_breach_decision
WHERE breach_id = br.id
ORDER BY creation_date_time DESC, id DESC)
LEFT JOIN {h-schema}breach AS child_br ON br.id = child_br.parent_breach_id
WHERE br.status = 'APPROVED' AND vbd.end_date = NULL <--------------------SYNTAX ERR HERE
OR br.status = 'DECLINED' AND br.completion_date_time > '2021-01-28 13:02:14'
OR br.status = 'IN_PROGRESS'
OR br.creation_date_time > '2021-01-28 13:02:14'
AND child_br.id IS NULL
AND CASE br.status
WHEN 'IN_PROGRESS' THEN vbr_approve.start_date
WHEN 'APPROVED' THEN vbd.start_date
WHEN 'CANCELLED' THEN vbd.start_date
ELSE NULL
END IS NOT NULL AND COALESCE(lim.policy_enterprise_id, d.policy_enterprise_id) IN (6)
) AS issue
This is actually version issue. In latest version of SQL support like
create procedure sp_name
(
#name varchar(50) NULL
)
...
But the older version of SQL doesn't support with this way. For older version we need to provide '=NULL'
There is some syntax error due to {h-schema}, remove {h-schema} and your code has no syntax error. Remove {h-schema} and your code works fine.

How can I use join in SQL to delete record?

I hava a problem with my program I'm trying to delete a record from a table using a join with Java this is my code:
try{
String sql ="DELETE f FROM facture f INNER JOIN client c ON f.idClient=c.id WHERE c.nom= ? ORDER BY idFact DESC LIMIT 1";
PreparedStatement pr = conn.prepareStatement(sql);
pr.setString(1,nom);
pr.executeUpdate();
System.out.println("supprimer");
}catch (SQLException e){
e.printStackTrace();
}
and this is the error :
java.sql.SQLSyntaxErrorException: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near 'ORDER BY idFact DESC LIMIT 1' at line 1.
In MySQL/MariaDB you have a choice:
You can use ORDER BY and LIMIT and the FROM can only refer to one table.
You can have a FROM that refers to multiple tables.
The solution? Rephrase the query:
DELETE FROM facture f
WHERE EXISTS (SELECT 1
FROM client c
WHERE f.idClient = c.id AND c.nom = ?
)
ORDER BY f.idFact DESC
LIMIT 1;
Or you can use a subquery to get the row to delete:
DELETE f
FROM facture f JOIN
(SELECT f.idFact
FROM facture f JOIN
client c
ON f.idClient = c.id AND c.nom = ?
ORDER BY f.idFact DESC
LIMIT 1
) ff
ON ff.idFact = f.idFact

could not read column value from result set in Hibernate Native Query

SELECT
CONCAT(CREG.FIRSTNAME, ' ', CREG.LASTNAME) AS NAME,
CASE WHEN CR.CAMPAIGNTYPE = 'NPS'
THEN NPSSCORE
ELSE CSATSCORE END AS SCORE,
IFNULL(cast(CC.TEXT AS CHAR(255)), '') AS COMMENTS,
CREG.ID AS CLIENTID,
CR.ID AS CAMPAIGNRESPONSEID,
CI.ID AS ISSUEID
FROM CUSTOMER_ISSUES CI INNER JOIN (SELECT DISTINCT ISSUEID
FROM ISSUE_DEPARTMENT_MAPPING
WHERE CUSTOMERUSERID = 91 AND ISSUE_STATUS = 'New') IDM
ON CAST(CI.FEEDBACK_DATE AS DATE) BETWEEN '2016-06-05' AND '2016-06-11' AND IDM.ISSUEID = CI.ID
INNER JOIN CAMPAIGN_RESPONSE CR ON CR.ID = CI.CAMPAIGN_RESPONSE_ID
INNER JOIN CLIENT_REGISTRATION CREG ON CREG.ID = CR.RESPONSECUSTOMERID
LEFT OUTER JOIN CAMPAIGN_COMMENTS CC ON CC.CAMPAIGN_RESPONSE_ID = CR.ID;
The above query is running in the mysql-console properly ,but when I am integrating with the Hibernate,following error is thrown by Hibernate.
[BigIntegerType] could not read column value from result set: ID; Column 'ID' not found.
Try getting rid of the alias names in your SQL query.
Basically what happens here is when you run
SELECT
CONCAT(CREG.FIRSTNAME, ' ', CREG.LASTNAME) AS NAME,
CASE WHEN CR.CAMPAIGNTYPE = 'NPS'
THEN NPSSCORE
ELSE CSATSCORE END AS SCORE,
IFNULL(cast(CC.TEXT AS CHAR(255)), '') AS COMMENTS,
CREG.ID AS CLIENTID,
CR.ID AS CAMPAIGNRESPONSEID,
CI.ID AS ISSUEID
in JDBC it returns the column as CREG.ID instead of ClientID.
So try running the query without the aliases, typically, there is a problem in JDBC with this. If you still insist on using aliases,add the following entry to JDBC URL in configuration file
[useOldAliasMetadataBehavior=true]

OpenJPA: how to construct a GROUP BY query with a group count

In JPQL I want to construct the equivalent query to this:
select *, count(*) as finger_count from page_delta_summary
where delta_history_id = ? and change_type = ? group by fingerprint;
where fingerprint is a varchar field in table page_delta_summary. What I have is this:
select d, count(d) as finger_count from PageDeltaSummary d
where d.deltaHistoryId = :deltaHistoryId and d.type = :pageDeltaType
GROUP BY d.fingerprint"
where PageDeltaSummary is my entity. But I'm getting the following exception:
org.apache.openjpa.persistence.ArgumentException: Your query on type "class com.su3analytics.sitedelta.model.PageDeltaSummary" with filter "select d, count(d) from PageDeltaSummary d where d.deltaHistoryId = :deltaHistoryId and d.type = :pageDeltaType GROUP BY d.fingerprint" is invalid. Your select and having clauses must only include aggregates or values that also appear in your grouping clause.
The query works fine if I remove either count(d) as finger_count or the GROUP BY.
Any suggestions?
Thanks
Your original SQL query doesn't make sense, therefore you can't convert in into JPQL.
I guess you want to get count of page_delta_summary rows satisfying where conditions for each fingerprint. If so, the SQL query looks like this:
select fingerprint, count(*) as finger_count from page_delta_summary
where delta_history_id = ? and change_type = ? group by fingerprint;
and JPQL - like this:
select d.fingerprint, count(d) from PageDeltaSummary d
where d.deltaHistoryId = :deltaHistoryId and d.type = :pageDeltaType
GROUP BY d.fingerprint
These queries return pairs <fingerprint, finger_count> instead of full page_delta_summary rows (or entities).

Categories