springboot java mysql syntax error at parameter - java

I have this application, java spring boot and mysql db.
When i try to run the following query, i get this error.
You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'email ='rahul#gmail.com.com'' at line 1
Does anyone know know why?
#Query(value = "SELECT voucher_code FROM voucher INNER JOIN "
+ "offer ON offer.name = voucher.offer "
+ " email =:email", nativeQuery = true)
List<Voucher> getVouchers(#Param("email") String email);

You are missing something between the two conditions offer.name = voucher.offer and email =:email, probably a WHERE, perhaps an AND/OR. I guess you wanted this:
#Query(value = "SELECT voucher_code FROM voucher INNER JOIN "
+ "offer ON offer.name = voucher.offer "
+ "WHERE email =:email", nativeQuery = true)
List<Voucher> getVouchers(#Param("email") String email);

Related

JPA parameter outside a where clause

I would like to know if the is a way to build a JPA query with parameter outside of the where clause. This query works fine in my database manager.
There is my query :
#Query(value = "SELECT q.quote, q.author, q.display_at, count(ql.*) AS like, (SELECT '{:userUUID}'::uuid[] && ARRAY_AGG(ql.user_uuid)::uuid[]) AS liked " +
"FROM quotes q " +
"LEFT JOIN quotes_likes ql ON ql.quote_uuid = q.uuid " +
"WHERE display_at = :date " +
"GROUP BY q.quote, q.author, q.display_at;", nativeQuery = true)
Optional<QuoteOfTheDay> getQuoteOfTheDay(UUID userUUID, LocalDate date);
I have the following error when the query is called : ERROR: syntax error at or near ":"
By default, Spring Data JPA uses position-based parameter binding. We can also use named parameter with #Param annotation to give a method parameter a concrete name and bind the name in the query. As you are trying to use the named parameter try using the below snippet with #Param annotations.
Optional<QuoteOfTheDay> getQuoteOfTheDay(#Param("userUUID") UUID userUUID, #Param("date") LocalDate date);
ERROR: syntax error at or near means that you need to escape casting colons.
Every : needs to be replaced by \\:
(SELECT ARRAY[:userUUID]'\\:\\:uuid[] && ARRAY_AGG(ql.user_uuid)\\:\\:uuid[]) AS liked
OR use double colons
(SELECT ARRAY[:userUUID]::::uuid[] && ARRAY_AGG(ql.user_uuid)::::uuid[]) AS liked
OR use Cast instead of colons
(SELECT cast(ARRAY[:userUUID] as uuid[]) && cast(ARRAY_AGG(ql.user_uuid) as uuid[])) AS liked
The second problem is that you need to create an array with a query parameter.
Try ARRAY[:userUUID] instead of {:userUUID}
Full query example:
#Query(value = "SELECT q.quote, q.author, q.display_at, count(ql.*) AS like, (SELECT ARRAY[:userUUID]\\:\\:uuid[] && ARRAY_AGG(ql.user_uuid)\\:\\:uuid[]) AS liked " +
"FROM quotes q " +
"LEFT JOIN quotes_likes ql ON ql.quote_uuid = q.uuid " +
"WHERE display_at = :date " +
"GROUP BY q.quote, q.author, q.display_at;", nativeQuery = true)
Optional<QuoteOfTheDay> getQuoteOfTheDay(UUID userUUID, LocalDate date);
As you are trying to pass method parameters to the query using named parameters, We define these using the #Param annotation inside our repository method declaration.
Each parameter annotated with #Param must have a value string matching the corresponding JPQL or SQL query parameter name.
#Query(value = "SELECT q.quote, q.author, q.display_at, count(ql.*) AS like, (SELECT '{:userUUID}'::uuid[] && ARRAY_AGG(ql.user_uuid)::uuid[]) AS liked " +
"FROM quotes q " +
"LEFT JOIN quotes_likes ql ON ql.quote_uuid = q.uuid " +
"WHERE display_at = :date " +
"GROUP BY q.quote, q.author, q.display_at;", nativeQuery = true)
Optional<QuoteOfTheDay> getQuoteOfTheDay(#Param("userUUID") UUID userUUID,#Param("date") LocalDate date);
Refer this for more details on how to use the #Query annotation.

Spring JPA Query is not recognizing Spatial Types

I'm trying to make a native query request through spring JPA Query annotation using Spacial data types.
The query works perfectly when asked to execute through the console or even in the database.
But when he is asked to be used through Spring.
Does anyone know what I'm doing wrong? or there is a better way to achieve the same result (leaving all the calculations DB sided)?
Thank you in advance
This is the query I'm trying to execute. Again, it works through console but fails to execute through spring boot request
#Query(value = "SELECT TOP 1 * FROM Vehicles v " +
"JOIN Bikelots l ON l.BikeLotId = v.BikeLotId " +
"JOIN BikeTypes b ON b.BikeTypeId = l.BikeTypeId " +
"WHERE b.BikeTypeId = ?1 " +
"ORDER BY " +
"Geography::STGeomFromText(v.Point.MakeValid().STAsText(),4326) " +
".STDistance(Geography::STGeomFromText(Geometry::Point(?2,?3,4326).MakeValid().STAsText(),4326)) "
, nativeQuery = true)
com.microsoft.sqlserver.jdbc.SQLServerException: Incorrect syntax near 'Geography:'.
Im using this dialect in application.properties
spring.jpa.database-platform=org.hibernate.spatial.dialect.sqlserver.SqlServer2008SpatialDialect
The given error was caused because jpa hibernate recognizes the character ":" as a placeholder for an upcoming variable.
By placing the query in a String variable, then adding "\\" before each ":" and assigning the string to the value of #Query, solved the problem. See code for example
String query = "SELECT TOP 1 * FROM Vehicles v " +
"JOIN Bikelots l ON l.BikeLotId = v.BikeLotId " +
"JOIN BikeTypes b ON b.BikeTypeId = l.BikeTypeId " +
"WHERE b.BikeTypeId = ?1 " +
"ORDER BY " +
"Geography\\:\\:STGeomFromText(v.Point.MakeValid().STAsText(),4326) " +
".STDistance(Geography\\:\\:STGeomFromText(Geometry\\:\\:Point(?2,?3,4326).MakeValid().STAsText(),4326)) ";
#Query(value = query, nativeQuery = true)

org.postgresql.util.PSQLException: ERROR: column "id" does not exist - Java Web Service

I am developing a java web service that is deployed in wildly. It is connected to a postgresql database.
In this database, I have a table called xx_activity. In it there is a column called "id", which is also the primary key.
Here is the query used to create the table:
CREATE TABLE xx_activity
(
id serial NOT NULL,
baseitemid integer
);
to connect to this table, I use the following java code:
conn = postgresVoyateDBConnection();
query = conn.prepareStatement("select id, baseitemid" +
"from xx_activity " +
"where \"id\" = ? ");
query.setInt(1, id);
ResultSet rs = query.executeQuery();
However, when I call the method that includes this code, I get an error:
org.postgresql.util.PSQLException: ERROR: column "id" does not exist
Position: 8
This is confusing because I certainly have this column. i added escape characters as per this answer, but it did not solve the issue.
Also note that queries without the where clause, like:
conn = postgresVoyateDBConnection();
query = conn.prepareStatement("select id, baseitemid " +
"from xx_activity");
ResultSet rs = query.executeQuery();
work perfectly.
I have also tried without using escape characters but it gives the same error. I also checked in pgadmin and there is no trailing space in the column name, neither are there any upper case letters involved (in which case, the other select query shouldn't have worked?).
How can this be fixed?
Fixed this, the issue was a missing space. After the first line of the query, there needs to be a space as belows:
query = conn.prepareStatement("select id, baseitemid " +
"from xx_activity " +
"where \"id\" = ? ");
EDIT: escape charactors not needed for id; so final answer should be:
query = conn.prepareStatement("select id, baseitemid " +
"from xx_activity " +
"where id = ? ");

JPA use IN clause with objects

I am facing a problem usign JPA, and more specifically using a IN clause.
The best way is, I think, to show you my code :
#NamedQuery(name = "Commande.findCustom", query = "SELECT DISTINCT [myFields] "
+ "FROM Commande c WHERE "
+ "[SomeCriterias] AND "
+ "c.ID IN (SELECT t.ID FROM SubTable t "
+ "WHERE t.IDX IN :param) AND [otherCriterias]"),
I then get an error from MySQL :
You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '.ID FROM SubTable t1 WHERE (t1.IDX IN (168)'
I am looking for a response but can't find anything ...
I tied to delete a IN clause, the problem is still the same (so it's not a double IN use problem)
my :param is a List of objects, that i got by using the Object.find() method. As you can see, it returns the ID (168). But I can't seem to find the problem ...
Any help would be greatly appreciated, thank you
EDIT : Full query
#NamedQuery(name = "Commande.findCustom", query = "SELECT DISTINCT c.idChargement, c.libelle, "
+ "c.codeTransporteur, c.reference, c.dateCreation, c.dateChargementPrevu, "
+ "c.dateValidationChargement, c.dateLivraisonPrevue, c.codeDestinataire, "
+ "c.raisonSocialeDestinataire, c.adresseDestinataire, c.codePostalDestinataire, "
+ "c.villeDestinataire, c.paysDestinataire, c.contactDestinataire, "
+ "c.telephoneDestinataire, c.mailDestinataire, c.poidsCommande, c.nombreColis, "
+ "c.nombreUniteManutention, c.typeUniteManutention, c.prendreRDV, c.commentaires "
+ "FROM Commande c WHERE "
+ "c.idChargement = :idChargement AND c.codeTransporteur = :codeTransporteur AND "
+ "(c.dateCreation BETWEEN :dateDebut AND :dateFin) AND "
+ "c.idDernierStatut IN (SELECT l.idListeStatutsCommande FROM Listestatutscommande l "
+ "WHERE l.idStatut IN :idStatut) AND c.raisonSocialeDestinataire = :raisonSociale AND "
+ "c.adresseDestinataire = :adresseDestinataire AND c.codeDestinataire = :codeDestinataire "
+ "AND c.codePostalDestinataire = :codePostal AND c.villeDestinataire = :villeDestinataire "
+ "AND c.paysDestinataire = :codePays")
And the Error Message
You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '.idListeStatutsCommande FROM listestatutscommande t1 WHERE (t1.IdStatut IN (168)'
As you are getting error from MYSQL not Hibernate, you could try to find out what query actually is generated. To do this, use proxy invoker like p6spy and then everything should be clear. Check p6spy site. When you do, try to invoke such generated SQL yourself and try to fix it. I used such method when I had some troubles using JPA's joins fetches and stuff. Very helpfull in diagnosing such problems.
Ok so I found the problem, and then the answer. Thanks #Antoniossss, the fact is that I was looking at the wrong part of the query.
The error was here : c.idDernierStatut IN ...
The fact is that this part is a foreign key. And when you want to search on it, you have to consider it as an object. So the correct form is c.idDernierStatut.idListeStatutsCommande IN to get the ID.
Thank you to both of you for your time anyway !

Relation "table name" doesn't exist postgresql

Hi I'm doing a query in java, i have java and posgres connected with the driver 9.3-1102-jdbc41
This is my query: query = "SELECT * FROM" +"\"users\" "+ " where user="+"'"+name+"'"+"and pass =" +"'"+pass+"'";
when I run it, this error appears:
Relation "users name" doesn't exist
Here and in others sites a possible solution is checking the quotes or the capital letters.
But I´m sure about the capital letters and this is what I tried:
query = "SELECT * FROM" +"\"users\" "+ " where user="+"'"+name+"'"+"and pass =" +"'"+pass+"'";
query = "SELECT * FROM users where user="+"'"+name+"'"+"and pass =" +"'"+pass+"'";
query = "SELECT * FROM" +"\"sysmar.users\" "+ " where user="+"'"+name+"'"+"and pass =" +"'"+pass+"'";
Error relation users does not exist
"SELECT * FROM users where user="+name+"and pass =" +pass;
syntax error near to pass
Thanks in advance for your answers and time
try:
"SELECT * FROM users where \"user\" ='"+name+"'and pass ='" +pass+"'";
But it's harmful for sql injection. See PreparedStatements.
For PostgreSQL you shouldn't need to put quotes around the table name unless it's a reserved keyword. Users isn't a keyword, but user just so happens to be one of them.
Your query is hard enough to read with the extra concatenation operations and spacing issues. Perhaps there is a syntax error and you just need to clean it up:
q = "SELECT * FROM users WHERE \"user\" = '" + name + "' AND pass = '" + pass + "'";
You want the final evaluated string to look like (for example):
SELECT * FROM users WHERE "user" = 'cory' AND pass = '12345';
But as others have mentioned, you should also switch to using prepared statements. This code is probably vulnerable to SQL injection attacks.
You really shouldn't concatenate variables with SQL queries, you are becoming vulnerable to SQL injection then. You better be using Prepared Statements which will allow you to write queries in more readable and secure fashion.
Connection conn = DriverManager.getConnection(...);
String queryString = "SELECT * FROM users WHERE user = ? AND pass = ?";
PreparedStatement query = conn.prepareStatement(queryString);
query.setString(1, name);
query.setString(2, password);
ResultSet result = query.executeQuery();

Categories