Combine JPA Query annotation with Oracle sample method - java

i am trying to pass a parameter into a JPA query
Example code
#Query(value =
"select *\n"
+ "from adress sample(:percentile)\n"
+ "where adress.number in (:adressNumbers)\n"
+ "fetch first (:rows) rows only,"
+ "nativeQuery = true
List<X> sampleExample(Integer rows, List<Integer> adressNumbers, Double percentile)
But i get an error because of the sample(:percentile).
If i just hardcode a number in there it works but not with a param.
Is there a way to escape the brackets or something similar?
Thx

The error is on the following part
from adress sample(:percentile)
Unfortunately it does not belong to the where part of the query and so the parameter passed :percentile can't be bound to the query.
There is not any quick fix around this. You won't be able to use a method parameter that will be able to be bound in the query in the part that you want it to be, because parameters can only be bound in the where part of the query.

Related

Postgres metrics query

I am new in the database side. My Question is, how to append a piece of query as param arguments. In my logic we are trying to append query using below
GET_DATA= "SELECT [:metrics] from table name"
am passing metrics as argument like below
paramMap.put("metrics", "name,age");
when am executing the query using query runner.
ResultSet rs = queryRunner.runQuery(context, GET_DATA, paramMap, RESULT_SET_HANDLER);
The output of the query like below
SELECT 'name,age' from table name
How can i avoid single quotes from the query?
I have tried these two changes but getting SQL error
[metrics]
metrics
If we put similar syntax with a condition like where colum_name=[:abc],its work fine for me.
Expecting a better solution.
Try this:
String columns = paramMap.get("metrics");
GET_DATA = "Select" +
columns +
" FROM" +
" name";

TypedQuery error "Not all named parameters have been set" when they had. JPA / Hibernate

I'm trying to build and execute a dynamic query that looks like this:
String query = "SELECT e FROM Employee e WHERE (1=1) AND (UPPER(e.lastName) LIKE :lastName)";
final TypedQuery<Employee> dbQuery = entityManager.createQuery(query, Employee.class);
dbQuery.setParameter("lastName", "%" + value.toString().toUpperCase() + "%"));
But it fails with this error:
org.hibernate.QueryException: Not all named parameters have been set: [lastName]
Most interesting is that in debug mod i can see that dbQuery has a bind for "lastName" parameter and contains the specified value inside its "parameterRegistrations" field. So i have no idea.
Alternative with using positional parameters like
dbQuery.setParameter(1, "%" + value.toString().toUpperCase() + "%")); is not my case, so pls lets do not discuss it.
This question is similar to mine but it's still unanswered.
Sorry guys! It was my inattention. A super strange and legacy code was there, which was creating a new instance of TypedQuery much later based on my query, but without parameters. I didn't expect it. That was the reason.

Hibernate native SQL does not return correct result comparing to database

I have this native query:
"SELECT DATE_FORMAT(createdDate, \"%Y-%M\") AS open_month, :" + filter
+ " AS filterName, COUNT(id) AS counts from cases group by open_month, :"
+ filter + " ;"
And then use setResultTransformer and Transformers.aliasToBean to convert to my DTO.
In database, Feb has two records using the query that Hibernate print out
SELECT
DATE_FORMAT(createdDate, "%Y-%M") AS open_month,
? AS filterName,
COUNT(id) AS counts
FROM
cases
GROUP BY
open_month,
?;
But when I get query.list(), 2017-Feb has only one record and the counts is 5, meaning that two records are merged.
Does anyone know why is this and how to return the exact result?
It seems like the same parameter will break the query like this: Using hibernate named parameter twice
If I use different parameter names then it works fine

UCASE and UPPER sql functions

I am trying to do the following query:
String query = "SELECT * FROM EMP WHERE UCASE(LAST_NAME) ";
query += "LIKE '" + lastName.toUpperCase() + "%'";
in an example of usage of an servlet to access to a database
But I am getting the error message:
Excepcion java.sql.SQLSyntaxErrorException: ORA-00904: "UCASE": invalid identifier
On the other hand, when I use the UPPER sql function, the example works but the results do not show the values of the LASTNAME column in uppercase. I do not understand what happens.
You're just comparing the upper case values, but you're selecting the actual values with select *
to get the uppercase name in your resultset you need to use UPPER in your select list, not UCASE, like this:
String query = "SELECT UPPER(LAST_NAME) AS UPPERNAME, * FROM EMP WHERE UPPER(LAST_NAME) ";
query += "LIKE '" + lastName.toUpperCase() + "%'";
What your code is doing here is building a query string named query. Once query is complete, it will be sent to the database for parsing and running.
When you are building a query to the database, you have to use the built-in database functions for the part of the query that the database is going to parse and run. So, in your example, Java is doing toUpperCase on lastName and then putting that literal into the query string that will go to the database. UPPER(LAST_NAME) is going into the query string as is, it will get passed to the database just like that and run by the database. So it needs to be a function that the database can parse and run: an Oracle function, not a Java function.
UCASE is a DB2 function & not Oracle. For Oracle, you need to use UPPER .
Second part of your question is already answered by James Z.
Having said that, I am answering because previous answers didn't pointed out SQL injection problem with the way you listed your query.
Make it a habit to always execute parametrized queries with jdbc & not by directly appending values to query string.
String query = "SELECT * FROM EMP WHERE UCASE(LAST_NAME) LIKE ? ";
Your parameter would be - lastName.toUpperCase()+"%"
SQL Injection

Get SQL String substituted with parameters using java

Is there any easy way to get a completed SQL statement after parameter substitution?
I am using elasticsearch-sql to query elastic search with sql statements, however I have to submit the query with all the parameters substituted.
I tried Hibernate Query getQueryString, but the parameter substitution is not happening for those sql strings.
The following sql string is produced:
"SELECT * FROM USER WHERE NAME=? AND SURNAME=?"
rather than:
"SELECT * FROM USER WHERE NAME='Selva' AND SURNAME='Esra'
Appreciate any better idea/thoughts?
1. Named parameters
This is the most common and user friendly way. It use colon followed by a parameter name (:example) to define a named parameter. See examples…
String hql = "SELECT * FROM USER WHERE NAME= :userName AND SURNAME= :surName";
Query query = session.createQuery(hql);
query.setParameter("userName ", "userName");
query.setParameter("surName", "SurName");
List results = query.list();
An object-oriented representation of a Hibernate query. A Query instance is obtained by calling Session.createQuery(). This interface exposes some extra functionality beyond that provided by Session.iterate() and Session.find():
a particular page of the result set may be selected by calling setMaxResults(), setFirstResult()
named query parameters may be used
the results may be returned as an instance of ScrollableResults
Named query parameters are tokens of the form :name in the query string. A value is bound to the integer parameter :foo by calling
setParameter("foo", foo, Hibernate.INTEGER);
for example. A name may appear multiple times in the query string.
JDBC-style ? parameters are also supported. To bind a value to a JDBC-style parameter use a set method that accepts an int positional argument (numbered from zero, contrary to JDBC).
You may not mix and match JDBC-style parameters and named parameters in the same query.
2. Positional parameters
It’s use question mark (?) to define a named parameter, and you have to set your parameter according to the position sequence. See example…
Java
String hql = "from Stock s where s.stockCode = ? and s.stockName = ?";
List result = session.createQuery(hql)
.setString(0, "7277")
.setParameter(1, "DIALOG")
.list();
This approach is not support the setProperties function. In addition, it’s vulnerable to easy breakage because every change of the position of the bind parameters requires a change to the parameter binding code.
Java
String hql = "from Stock s where s.stockName = ? and s.stockCode = ?";
List result = session.createQuery(hql)
.setParameter(0, "DIALOG")
.setString(1, "7277")
.list();
Conclusion
In Hibernate parameter binding, i would recommend always go for “Named parameters“, as it’s more easy to maintain, and the compiled SQL statement can be reuse (if only bind parameters change) to increase the performance.

Categories

Resources