#Resolved - Positional parameter does not exist in query // stored function call - java

I have this method to call a stored function from ORACLE, in java (spring) - using entity manager + createNativeQuery ..
(...)
String set_professional = "{? = call
pk_backoffice.set_professional(?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?}";
//32 parameters IN
query = entity.createNativeQuery(set_professional);
(...)
And everytime I try to test it, it shows:
Positional parameter does not exist: 31 in query: {? = call (...)
But do I have something at position 31..it exists..
query.setParameter(31, prof.getFax()); // fax
Also, I started the parameters at 1 cause in previous exceptions it said it was 1-based
I've tried with a string and a null value instead of the get, still the same outcome..
About the query, I also counted the ? many times, so I'm sure it has 32 (for parameters) + 1(return - first ?)...
Can anyone help?

Found a solution, I replaced all ? for variables, even the first one, and the error disappeared.

Related

JPA calling stored procedure with argument

I have this procedure in my postgreSQL database:
CREATE OR REPLACE FUNCTION getItemsForCategory(categoryId integer)
RETURNS SETOF ITEM AS $_$
DECLARE
result ITEM;
BEGIN
FOR result IN SELECT *
FROM item it
JOIN item_category itcat ON it.id = itcat.item_id WHERE itcat.category_id = categoryId LOOP
RETURN NEXT result;
END LOOP;
END; $_$ LANGUAGE 'plpgsql';
which works excellent using terminal, but I have trouble with calling it using JPA. Here is my code snippet(4 is value of argument cateforyId):
transactions.begin();
final StoredProcedureQuery storedProcedureQuery = entityManager.createStoredProcedureQuery("getItemsForCategory");
storedProcedureQuery.setParameter(1,4).execute();
final List<ItemEntity> itemEntityList = (List<ItemEntity>) storedProcedureQuery.getResultList();
transactions.commit();
after running code above I receive this error:
Exception in thread "main" java.lang.IllegalArgumentException:
You have attempted to set a parameter at position 1 which does not exist in this query string getItemsForCategory
Has anyone some idea how to set the value of argument correctly? I've also tried to set parameter using 0 instead of 1, calling setParameter with others datatypes of arguments (String,Object) but everytime I am receiving familiar kind of error like the one, which is shown there. Thank you very much
You need to register your parameters, before setting values.
spq.registerStoredProcedureParameter("categoryId", int.class, ParameterMode.IN);
See this link.

IllegalArgumentException - Parameter with that name [name] did not exist

I have a this query on my code:
return Long.parseLong(getEntityManager().createQuery(
"SELECT COUNT(a) FROM ApartmentExtraType a WHERE a.accommodation.id = :idacc AND (LOWER(a.name) LIKE :name)",
Long.class)
.setParameter("idacc", accommodation.getId())
.setParameter("name", "%" + filterQuery.getFieldFilter("name").toString().toLowerCase() + "%")
getSingleResult().toString());
If the query don't find any element i have no problem, but if it found at least one element I have this error:
Last cause: Parameter with that name [name] did not exist WicketMessage: Error attaching this container for rendering:
[WebMarkupContainer [Component id = tbody]]
The name of the relative column is "name" and I'm sure. Other query seems to be identical to this one and they work fine. I don't know which is the problem
Looks like the issue is not with the column name it is with the parameter you are passing in called "name." The "idacc" one looks like it was grabbed correctly.
So this part is not working
filterQuery.getFieldFilter("name").toString().toLowerCase()
Try passing in a String and see if that works something like
.setParameter("name", "ExampleName");
If that runs fine then there is something wrong with the getFieldFilter function
I resolved. The problem was that the query is composed in different method because it vary depending on user's input and in one of this method a variable was badly instantiated. So the JVM didn't find the part of the query with the [name] parameter.

Why is this Java query failing? returning 0 when there are results

Hi can anyone tell me why this java query is failing?
Query q = entityManager.createNativeQuery("SELECT m.* FROM MdmAudit m WHERE m.correlationID = :correlationId AND m.verb = :verb", MdmAuditDAO.class);
//Query q = entityManager.createNamedQuery("MdmAuditDAO.GetData");
q.setParameter("correlationId", resp.getHeader().getCorrelationID());
q.setParameter("verb", resp.getHeader().getVerb());
long result = (long) q.getFirstResult();
The namedQuery:
#NamedQuery( name="MdmAuditDAO.GetData", query="SELECT m FROM MdmAuditDAO m WHERE m.correlationId = :correlationId AND m.verb = :verb")
public class MdmAuditDAO implements Serializable {
I have getters and setter in my MdmAuditDAO class, and I have checked the naming of the variables, and they are identical as in the NamedQuery, so the problem does not lie there.
My problem is that I have three entries in my database, I should at least get one answer back but I get 0 in my result.
MdmAuditDAO is defined in my persistence.xml and in my ehcache.xml. So why is it that the result I get returned is 0? I have also tried to get an object returned or a list of objects, and it is the same result, nothing gets returned, but when I run my query in my mssql database I get results see picture below. It has nothing to do with the m.* I aslo get results when I use that in my SELECT statement.
EDIT 1: This is what I get from my hibernate log, and I do not know how to read this?
Hibernate:
select
mdmauditda0_.id as id1_7_,
mdmauditda0_.correlationID as correlat2_7_,
mdmauditda0_.messageID as messageI3_7_,
mdmauditda0_.meter_no as meter_no4_7_,
mdmauditda0_.noun as noun5_7_,
mdmauditda0_.payload as payload6_7_,
mdmauditda0_.source as source7_7_,
mdmauditda0_.subtype as subtype8_7_,
mdmauditda0_.time as time9_7_,
mdmauditda0_.verb as verb10_7_
from
MdmAudit mdmauditda0_
where
mdmauditda0_.correlationID=?
Anything I have to set, to get more information? I am using the following jars
And my java version is 1.7.0_79.
I found the solution http://www.objectdb.com/api/java/jpa/Query/getFirstResult returns the position of the first element, but I was a bit confused by the phrase
Returns 0 if setFirstResult was not applied to the query object.
Could not get my head around it to make any sense of it.
My solution now is that I just return a list of objects
Query q = entityManager.createNativeQuery("SELECT m.* FROM MdmAudit m WHERE m.correlationId = :correlationId AND verb = :verb", MdmAuditDAO.class);
//Query q = entityManager.createNamedQuery("MdmAuditDAO.GetData");
q.setParameter("correlationId", resp.getHeader().getCorrelationID());
q.setParameter("verb", resp.getHeader().getVerb());
List<MdmAuditDAO> mdmAuditList = q.getResultList();
And then it works fine and I get results. So instead of the the result == 0 check I am doing later in my code I just do a NULL and isEmpty() check instead().
Side note: I have not tried to delete entries and then see what the result would be then in the q.getFirstResult() call but that would be a possibility and see what i get returned and then check on that value, properbly null?

How to pass null to SQL parameter in java?

I have a scenario where in i have to pass null to a SQL parameter through java but i am getting SQLGrammarException. If i am passing some value it works fine. Please guide if i am wrong somewhere.
Below is my code:
StringBuffer query;
query = new StringBuffer(
"SELECT * "+
"FROM table(package.func(travel_type => travel_search_type("+
"travel_place_no => :travelPlaceNo"+
")))" );
Query query1 = em.createNativeQuery(query.toString());
query1.setParameter("travelPlaceNo",null);
searchresults = query1.getResultList();
Exception:
org.hibernate.exception.SQLGrammarException
This is what i do through SQL Developer and it works fine:
SELECT *
FROM table(package.func(travel_type => travel_search_type(
travel_place_no => NULL))) ;
Please guide.
While calling the 2 argument signatures of the method, null is not an allowed value. You can use, instead, the 3 argument signature setParameter(String name,
Object val,
Type type) specifying the data type and it should work.
EDIT:
Ok, I see there is also another problem: even if the replacemente worked, what you are trying to execute is a >= NULL. In this case, I'm afraid that you are going to have to handle mannually the StringBuffer creation. Maybe just force an always false condition without parameters if its null, like `1!=2', and otherwise just handle it as you are doing on your sql example (write mannually 'NULL' instead of the parameter placeholder).

Invoking procedure defaults without binding values to parameters in Jdbc

I am trying to call a PL/SQL procedure which has defaults defined for some of its parameters. I am doing this using CallableStatement in JDBC.
This procedure has a large number of parameters with defaults defined. I do not want to explicitly set the defaults in the Java code. Doing this would make maintaining the code harder. If the PL/SQL code changes , would have to make the same changes in the Java code too.
Is it possible to accomplish this in JDBC ? For instance just bind values to the parameter you are interested in and ignore the rest.
I tried this on the following sample procedure :
-- PURPOSE: Takes a parameter which has defaults set. Returns the value of the same parameter
-- Example of: FUNCTION that takes a parameter with DEFAULT values
FUNCTION handle_defaults(empId IN NUMBER DEFAULT 20 , empCity IN VARCHAR2) RETURN NUMBER IS
BEGIN
RETURN empId;
EXCEPTION
WHEN others THEN
dbms_output.put_line('Error!');
END handle_defaults;
Here is the relevant portions of the code (NOTE: Have stripped off the try catch block , cleaning up of database resources etc for sake of readability)
// Create a database connection
conn = DriverManager.getConnection(DB_URL, DB_USER, DB_PWD);
// Create a query string
String queryStr = "{ ? = call HR.EMP_PKG.handle_defaults( ? , ? ) }";
// Create a Callable Statements
callStmt = conn.prepareCall(queryStr);
// Bind values to the IN parameter
callStmt.setString(3, "Mumbai");
// Register OUT parameter
callStmt.registerOutParameter(1, java.sql.Types.NUMERIC);
// Execute the Callable Statement
callStmt.execute();
// Retrieve the value of the OUT parameter
parameterValue = callStmt.getInt(1);
System.out.println("Value returned : " + parameterValue);
I get the following error:
Exception occured in the database
java.sql.SQLException: Missing IN or OUT parameter at index:: 2
Database error code: 17041
As a desperate attempt I also tried to pass Nulls for those parameters. Just included the following line:
callStmt.setNull(2, java.sql.Types.NUMERIC);
I get the following result:
Value returned : 0
That makes sense bcoz setNull supplies SQL Null to the parameter.
I am using Oracle 11g and Oracle 12c Jdbc Driver Version 12.1.0.2.
I don't think there's a simple answer to this question, and that's not because of JDBC, but because of Oracle.
Put simply, the only way I know of calling a procedure and using the default value for a parameter is to not specify the parameter when you call the procedure.
If you are writing
String queryStr = "{ ? = call HR.EMP_PKG.handle_defaults( ? , ? ) }";
you are always specifying both parameters, so you can never use the default value for one of them. If you only want to specify one of them and use the default for the other, write:
String queryStr = "{ ? = call HR.EMP_PKG.handle_defaults( empCity => ? ) }";
In this case you need to specify the parameter name in the call, as the first parameter is the optional one. If the second parameter was optional instead, the parameter name can be dropped.
Unfortunately, this becomes quite complicated for your real procedure with lots of parameters. What I would do would be to:
Use a StringBuilder to build up the procedure call string.
Run through the parameters, adding paramName => ? parts to it for each parameter you have a value for. Ensure the parts are separated by commas.
Prepare a CallableStatement using the output of the StringBuilder.
Run through the parameters again and call various setString/setInt/setDate/etc. methods on the CallableStatement for each parameter you have a value for.

Categories

Resources