No value specified for parameter 1 - is the query too long? - java

I am running a simple insert using jooq:
InsertValuesStep6<...>
insertInto =
withContext()
.insertInto(
MyTable,
MyTable.ID);
for (Integer id : ids) {
insertInto = insertInto.values(id);
}
insertInto.execute();
I simplified it a bit for the question, there are couple of more fields in each row.
It usually works fine, but once in a while get an exception: org.postgresql.util.PSQLException: No value specified for parameter 1.
So I suspect it's not a syntax issue but scale issue.
Maybe the actual query is trimmed by jooq somehow?

Related

Parameterized hibernate query causing where clause failure

The following code snippet works as expected, returning a list containing a dozen rows.
String hql = "select assetDate, sum(variable) as variable from Table where assetDate >= '30-JUN-19' and assetDate < '30-JUN-20' and ver= '"+ver+"' group by assetDate order by assetDate";
List results = session.createQuery(hql).list();
This code, however, returns an empty list, but no errors.
String hql = "select assetDate, sum(variable) as variable from Table where assetDate >= '30-JUN-19' and assetDate < '30-JUN-20' and ver= :ver group by assetDate order by assetDate";
List results = session.createQuery(hql).setString("ver",ver).list();
I cannot understand what might be causing the difference here.
In the log, I can see:
binding parameter [1] as [VARCHAR] - [the correct value]
So it looks like the variable is being bound properly, but since the output is incorrect, it clearly isn't. Does anyone have any idea what might be happening internally to cause this difference?
The column ver in the source table is of type CHAR( 20 BYTE), which is the only thing I can think of that might cause a problem, but even that seems somewhat unlikely.

Jpa returns more than one result although only one row is in database

I am running different JPA queries in the form of
Float getDepositVolumeByDepositIdDepositAndSpeciesIdSpeciesAndRangeIdRangeAndSubRangeIdSubrange(Long idDeposit, Long idSpecies, Long idRange, Long idSubRange); // this is one of the methods that fail
#Query("select stock.depositVolume from Stock s where s.deposit.idDeposit = ?1 and s.species.idSpecies = ?2 and s.range.idRange = ?3 and s.subrange.idSubrange = ?4")
Float getVolumeByDepositIdDepositAndSpeciesIdSpeciesAndRangeIdRangeAndSubRangeIdSubrange(Long idDeposit, Long idSpecies, Long idRange, Long idSubRange); // this one is just for ilustrative purpose and throws the exact same error
These two queries being just some of those that should return one row. Although the database has only one row corresponding to the data provided to the query, hibernate throws the following error message:
Result returns more than one elements
I have turned on hibernate query log and the query generated is the following for the first method:
select stock0_volume_stock as col_0_0_ from public.stock stock0_ where stock0_.id_deposit = ? and stock0_.id_species = ? and stock0_.id_range = ? and stock0_.id_sub_range = ?
with the correctly bound parameters. I ran the query on PostGres and it returns only one row with a float.
It is worth mentioning that my class declaration is:
public interface StockRepository extends QueryDslPredicateExecutro<Stock>, JpaRepository<Stock, long>
What I have ended doing is change those methods into
List<Stock> findFirstByDepositIdDepositAndSpeciesIdSpeciesAndRangeIdRangeAndSubRangeIdSubrange(Long idDeposit, Long idSpecies, Long idRange, Long idSubRange); // now it justly returns only one row, the first one
I usually suppose, and certainly on previous projects this was the behavior observed, that the first method should map the only result fetched from the database into the expected float
I am very interested what is the explanation of this behaviour.
If you do SELECT some-column FROM some-table WHERE... there is no way for jpa/hibernate to know that only one row matches the condition, on the contrary it must assume that many rows are returned and my guess is that it always uses the same logic for a query like this (assuming multiple rows) and that the error message is misleading here.
To get one row you would need a query with an aggregate function like SUM or COUNT as the only element in the SELECT clause. Maybe for fun you could try to use SUM in your original query and see if it returns the expected result.
Maybe this is more suitable as a comment than an answer but it felt like to long for a comment

DB2 jdbc execute function error [duplicate]

I'm using the statement below to update/insert some data to a table and, if I run it without parameters, it's fine. However, as soon as I try to execute it using parameters it throws:
SQL0418N - A statement contains a use of an untyped parameter marker, the DEFAULT keyword, or a null value that is not valid.
I've read the error information here, but I'm still struggling with why my statement won't execute.
--This statement works
MERGE Into AB.Testing_Table A
USING (VALUES('TEST', 'P')) B(TEST_ID, "ACTION")
ON (A.TEST_ID = B.TEST_ID)
WHEN NOT MATCHED THEN
INSERT (TEST_ID, "ACTION")
VALUES ('TEST', 'P')
WHEN MATCHED THEN
UPDATE SET TEST_ID = 'TEST'
,"ACTION" = 'P';
--This statement fails with error SQL0418N
MERGE Into AB.Testing_Table A
USING (VALUES(#TEST, #ACTION)) B(TEST_ID, "ACTION")
ON (A.TEST_ID = B.TEST_ID)
WHEN NOT MATCHED THEN
INSERT (TEST_ID, "ACTION")
VALUES (#TEST, #ACTION)
WHEN MATCHED THEN
UPDATE SET TEST_ID = #Test
,"ACTION" = #Action;
Thanks in advance for the help!
Basically, DB2 doesn't know what data types you're sending in on those parameters. I'm guessing you're either on an older version of DB2 (less than 9.7 on Linux/Unix/Windows, or on a Mainframe version older than 10.1), which doesn't do a whole lot of "automatic" type conversion. Or you're sending in NULL values (which still have to be "typed", strange as it sounds).
You can fix the problem by creating your parameter markers as typed parameters (I'm assuming data types here, use what would be appropriate):
MERGE INTO AB.TESTING_TABLE A
USING (VALUES (
CAST(#TEST AS CHAR(4))
,CAST(#ACTION AS CHAR(1))
)) B(TEST_ID, "ACTION")
ON (A.TEST_ID = B.TEST_ID)
WHEN NOT MATCHED THEN
INSERT (TEST_ID, "ACTION")
VALUES (B.TEST_ID, B.ACTION)
WHEN MATCHED THEN
UPDATE SET "ACTION" = B.ACTION
Additionally, since you're using the MERGE, you don't have to use parameters in the UPDATE or INSERT parts, you can refer to the values in the USING table you passed in. Also, since you're matching on TEST_ID, you don't need to include that in your UPDATE statement, since it wouldn't be updated, anyway.

How to do Cassandra CQL queries with Astyanax?

I'm using Astyanax version 1.56.26 with Cassandra version 1.2.2
Ok, a little situational overview:
I have created a very simple column family using cqlsh like so:
CREATE TABLE users (
name text PRIMARY KEY,
age int,
weight int
);
I populated the column family (no empty columns)
Querying users via cqlsh yields expected results
Now I want to programmatically query users, so I try something like:
ColumnFamily<String, String> users =
new ColumnFamily<String, String>("users", StringSerializer.get(), StringSerializer.get());
OperationResult<ColumnList<String>> result = ks.prepareQuery(users)
.getRow("bobbydigital") // valid rowkey
.execute();
ColumnList<String> columns = result.getResult();
int weight = columns.getColumnByName("weight").getIntegerValue();
During the assignment of weight a NPE is thrown! :(
My understanding is that the result should have contained all the columns associated with the row containing "bobbydigital" as its row key. I then tried to assign the value in the column named "weight" to the integer variable weight. I know that the variable columns is getting assigned because when I add some debug code right after the assignment, like so:
System.out.println("Column names = " + columns.getColumnNames());
I get the following output:
Column names = [, age, weight]
So why the null pointer? Can someone tell me where I went wrong? Also, why is there blank column name?
UPDATE:
Also if I try querying in a different manner, like so:
Column<String> result = ks.prepareQuery(users)
.getKey("bobbydigital")
.getColumn("weight")
.execute().getResult();
int x = result.getIntegerValue();
I get the following exception:
InvalidRequestException(why:Not enough bytes to read value of component 0)
Thanks in advance for any help you can provide!
I figured out what I was doing incorrectly. The style of querying I was attempting is not valid with CQL tables. To query CQL tables with Astyanax you need to chain the .withCQL method to your prepareQuery method; passing a CQL statement as the argument.
Information specific to using CQL with Astyanax can be found here.
I got this fixed by adding setCqlVersion
this.astyanaxContext = new AstyanaxContext.Builder()
.forCluster("ClusterName")
.forKeyspace(keyspace)
.withAstyanaxConfiguration(
new AstyanaxConfigurationImpl().setCqlVersion(
"3.0.0").setDiscoveryType(
And adding WITH COMPACT STORAGE while creating the table.

Retrieving a max date from DB2 in Java throwing wrong column type conversion exception

I have the following SQL that returns the max BILL_DATE based on some criteria. BILL_DATE is defined in the database as a DATE.
SELECT MAX(BILL_DATE)
FROM BILLTABLE
WHERE col1 = ? and
col2 = ?
But when I read the value from the resultSet.
bill.setBillDate(resultSet.getDate(1));
An exception is thrown:
Invalid data conversion: Wrong result column type for requested conversion. ERRORCODE=-4461, SQLSTATE=42815
I have also tried
bill.setBillDate(resultSet.getString(1));
But that doesn't return a date. It returns either 100, 200 or 300 which is obviously not correct.
Is there another way to do this? Am I doing something wrong?
Ash is right, how are you defining the date column?
Is it possible the column is timestamp? In that case try resultSet.getTimestamp(1))
I had two resultSets open in the function where I was reading in the BILL_DATE. I changed the code to the following and it works fine.
bill.setBillDate(resultSet1.getDate(1));

Categories

Resources