I have made a sql query now i need to add search from it. it needs to search from userfullname the given keyword query is working in postgresql but it is not working with CreateSqlQuery.
sqlQuery = "select * from ( " + sqlQuery + ") a where a.payeeName ilike :searchpayeename ";
SQLQuery query = sessionFactory.getCurrentSession().createSQLQuery(sqlQuery)
.addScalar("id", new LongType());
query.setParameter("searchpayeename", "%"+payee + "%");
It is not giving me result while if i run same query in sql it is giving result. Any Idea.
Operator iLike not work with jpql, only with native query.
If you want use jpql you need simulate the iLike function using toLowerCase() on both sides of query.
jpqlQuery = "SELECT a FROM EntityName a WHERE LOWER(a.payeeName) LIKE :searchpayeename";
SQLQuery query = sessionFactory.getCurrentSession().createSQLQuery(jpqlQuery)
.addScalar("id", new LongType());
query.setParameter("searchpayeename", "%" + payee.toLowerCase() + "%");
Or using createNativeQuery:
sqlQuery = "SELECT * FROM EntityName a WHERE " +
"LOWER(a.payeeName) LIKE LOWER(CONCAT('%',:searchpayeename, '%'))";
SQLQuery query = sessionFactory.getCurrentSession().createNativeQuery(sqlQuery)
.addScalar("id", new LongType());
query.setParameter("searchpayeename", "%" + payee.toLowerCase() + "%");
Related
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.
I am using following code to execute native SQL query with hibernate:
Query zonesQuery = session.createNativeQuery(
"Select * \n" +
"FROM dbo.Structure AS S\n" +
"JOIN dbo.StructureLocationType AS SLT ON SLT.StructureId = S.Id\n" +
"WHERE SLT.LocationTypeId = :lc").addEntity(StructureEntity.class);
zonesQuery.setParameter("lc", locationTypeID);
List<StructureEntity> zones = zonesQuery.list();
So it works and it gets me list of StructureEntity
now, because my sql query "join" from StructureLocationType table, is there possibility to get whole StructureLocationType row as well, still using single query?
Thank you.
It can be achieved with the following (notice curly braces in SQL and entities aliases):
Query query = session
.createNativeQuery(
"SELECT {S.*}, {SLT.*} " +
"FROM dbo.Structure AS S " +
"JOIN dbo.StructureLocationType AS SLT ON SLT.StructureId = S.Id " +
"WHERE SLT.LocationTypeId = :lc")
.unwrap(SQLQuery.class)
.addEntity("S", StructureEntity.class)
.addEntity("SLT", StructureLocationTypeEntity.class)
.setParameter("lc", locationTypeID);
List<Pair<StructureEntity, StructureLocationTypeEntity>> result = ((List<Object[]>) query.list())
.stream()
.map(p -> Pair.of((StructureEntity) p[0], (StructureLocationTypeEntity) p[1]))
.collect(Collectors.toList());
You can't get multiple Objects from one query.
But you could either select which columns you want and then iterate the returned Object array:
The query:
SELECT s.id, s.someColumn, slt.id, slt.structureId
FROM dbo.Structure AS s
JOIN dbo.StructureLocationType AS slt on slt.structureId = s.id
WHERE slt.locationTypeId = :lc
Then iterate over the Object array:
List<Object[]> result = query.getResultList();
Or you could create a view on your database and map it to a java entity using the Table annotation like it was a normal table:
#Entity
#Table(name = "STRUCTURE_LOCATION_TYPE_VIEW")
public class StructureAndLocationType {
// ...
}
I thought there is a way to map from a query to an Object without creating a DB view but couldn't find it right now.
Instead of creating an entity with column annotation, is it possible to get query result with column name? Like:
#Query(value = "select emp.emp_id, emp_fname, emp_lname, emp_division_id, emp_role_id," +
"(select count(*) from cheers.ch_kudos where kudos_receiver_id = emp.emp_id) as received_kudos_num, " +
"(select count(*) from cheers.ch_kudos where kudos_sender_id = emp.emp_id) as sent_kudos_num " +
"from cheers.ch_employee as emp where emp.emp_active_flag = 'true'",
nativeQuery=true)
List<Object> getAllEmployeesReport();
The return result only has values, but doesn't have column name.
Otherwise, it there a way to get PostgreSQL row_to_json result by Spring JPA?
#Query(value = "select row_to_json(t) from (select emp.emp_id, emp_fname, emp_lname, emp_division_id, emp_role_id," +
"(select count(*) from cheers.ch_kudos where kudos_receiver_id = emp.emp_id) as received_kudos_num, " +
"(select count(*) from cheers.ch_kudos where kudos_sender_id = emp.emp_id) as sent_kudos_num " +
"from cheers.ch_employee as emp where emp.emp_active_flag = 'true') t",
nativeQuery=true)
List<Object> getAllEmployeesReport();
It will throw JDBC 111 exception.
this is what i got
com.mysql.jdbc.exceptions.MySQLSyntaxErrorException: 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 'order by idconsumo' at line 1
java.lang.IllegalArgumentException: Cannot set a null TableModel
code
sSQL = "select c.idconsumo,c.idreserva,c.idproducto,p.nombre,c.cantidad,c.precio_venta "
+ ",c.estado from consumo c inner join producto p on c.idproducto=p.idproducto"
+ " where c.idreserva = " + buscar +" order by idconsumo";
but still save it in the database. If i exit the app and open it again then the
record is added
First of all as Jon suggested, use the parametrized SQL.
You need to make few changes to the SQL as below:
"select c.idconsumo, c.idreserva, c.idproducto, p.nombre, c.cantidad, c.precio_venta, c.estado from consumo c inner join producto p on c.idproducto=p.idproducto where c.idreserva = " + buscar +" order by c.idconsumo";
Make sure if buscar is a variable and c.idreserva is non-int column then add single quotes around it like c.idreserva = '" + buscar +"' and order by c.idconsumo
Using prepared statement:
String sql = "select c.idconsumo, c.idreserva, c.idproducto, p.nombre, c.cantidad, c.precio_venta, c.estado from consumo c inner join producto p on c.idproducto=p.idproducto where c.idreserva = ? order by c.idconsumo";
PreparedStatement prepStmt = conn.prepareStatement(sql);
//if buscar is string type
prepStmt.setString(1, buscar);
ResultSet rs = prepStmt.executeQuery();
Query syntax error. Please check:
String sql = " select c.idconsumo,c.idreserva,c.idproducto,p.nombre,"
+" c.cantidad,c.precio_venta, c.estado "
+" from consumo c inner join producto p on "
+" c.idproducto=p.idproducto "
+" where c.idreserva ='" + buscar +"' order by c.idconsumo ";
PreparedStatement would be more accurate to use.
A PreparedStatement is a special kind of Statement object with some useful features. Remember, you need a Statement in order to execute either a query or an update. You can use a PreparedStatement instead of a Statement and benefit from the features of the PreparedStatement.
The PreparedStatement's primary features are:
Easy to insert parameters into the SQL statement. Easy to reuse the
PreparedStatement with new parameters. May increase performance of
executed statements. Enables easier batch updates.
String sql = " select c.idconsumo,c.idreserva,c.idproducto,p.nombre,"
+" c.cantidad,c.precio_venta, c.estado "
+" from consumo c inner join producto p on "
+" c.idproducto=p.idproducto "
+" where c.idreserva = ? order by c.idconsumo ";
PreparedStatement preStmt = conn.prepareStatement(sql);
preStmt.setInt(1, buscar);
ResultSet rs = preStmt.executeQuery();
I wrote this query in java that gives me the list of tables and save them in data collection:
sql = "select * FROM information_schema.tables WHERE table_type = 'BASE TABLE'";
ResultSet rs = stmt.executeQuery(sql);
int count_table = 0;
while (rs.next()) {
table_list.add(rs.getString(3));
count_table += 1;
}
Table_list = table_list.toString();
Table_list is string.
But when i want to use this list in another query in this way:
sql="SELECT COLUMN_NAME FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME = '" + Table_list[t] + "'";
Gives me this error :
array required, but java.lang.String found
I used this in c# and worked well:
"SELECT COLUMN_NAME FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME = '" + tablelist[t].Trim() + "'";
What is the same way in java?
Thanks for help.
sql="SELECT COLUMN_NAME FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME = '" + Table_list[t] + "'";
should be changed to:
sql="SELECT COLUMN_NAME FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME = '" + table_list.get(t).trim() + "'";
In Java, brackets access is only allowed for plain arrays. You declare an array using brackets String[] stringArray. Internally, Java handles a char array inside the String.
Looking at your code, looks like you're confusing a String and a List<String (or ArrayList<String>).
In order to access to a List/ArrayList element, you should use get method (note that I'm using table_list, not Table_list):
//wrong
sql="SELECT COLUMN_NAME FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME = '" + table_list[t] + "'";
//right
sql="SELECT COLUMN_NAME FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME = '" + table_list.get(t).trim() + "'";
Note that by doing this, your code is weak to an SQL Injection attack. Instead, you should use PreparedStatement to handle this:
sql = "SELECT COLUMN_NAME FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME = ?";
PreparedStatement stmt = con.prepareStatement(sql);
stmt.setString(1, table_list.get(t));
ResultSet rs = stmt.executeQuery();
Also, please change the name of your variables, since table_list and Table_list can be easily confused by code readers (it would result confusing even to you).