Hibernate setParemeter 1-based or 0-based? QueryParameterException - java

Assuming everything else works like a charm (entities, named queries, native named queries) I'm facing weird exceptions while trying to run following query, where date column type is TIMESTAMP:
#NamedNativeQuery(name = "problematicQuery", query = "DELETE FROM mytable WHERE date < ?")
I'm trying to execute this query using following code, where date is java.sql.Timestamp:
Query deleteQuery = em.createNativeQuery("problematicQuery");
deleteQuery.setParameter(1, date);
deleteQuery.executeUpdate();
This code results in following exception:
org.hibernate.QueryParameterException: Position beyond number of declared ordinal parameters. Remember that ordinal parameters are 1-based! Position: 1
When I change the middle code line to this:
Query deleteQuery = em.createNativeQuery("problematicQuery");
deleteQuery.setParameter(0, date);
deleteQuery.executeUpdate();
I'll get the same exception with different position:
org.hibernate.QueryParameterException: Position beyond number of declared ordinal parameters. Remember that ordinal parameters are 1-based! Position: 0
I'm using JBoss 7.2.0.Final (Hibernate version is 4.2.0.CR1), Oracle 11g.
WHAT IS WRONG ? Am I missing something ?

Looks like you use wrong way
em.createNamedQuery("problematicQuery")
rather than
em.createNativeQuery("problematicQuery");
In your case a query created from string "problematicQuery" where no parameters exist

You should use named parameters inside JPA QL: #NamedNativeQuery(name = "problematicQuery", query = "DELETE FROM mytable WHERE date < :dt"
and deleteQuery.setParameter("dt", date);

Related

How to add date in mysql database from Hibernate/Spring Jpa

I use spring boot, and I want to add 1 year to a specific column in mysql database
String queryRecherche = "UPDATE myTable t SET t.dateDebut = DATE_ADD(t.dateDebut, INTERVAL 1 YEAR) WHERE.id = 3 ";
Query query = em.createQuery(queryRecherche);;
query.executeUpdate();
But I get the folowing error :
org.hibernate.query.sqm.ParsingException: line 1:66 no viable alternative at input 'DATE_ADD(t.dateDebut,INTERVAL1'
Have you please any suggestions to do this.
You're using Hibernate 6 (I can tell by the error message), so the correct HQL syntax to use is:
UPDATE MyEntity t SET t.dateDebut = t.dateDebut + 1 year WHERE t.id = 3
You had three errors in your query:
You referred to the name of a table instead of the name of an entity class in the UPDATE clause.
You used the unportable MySQL DATE_ADD function instead of the portable HQL date/time arithmetic described here.
The syntax of your WHERE clause was garbled.
Perhaps you meant for this to be a native SQL query, in which case you called the wrong method of Session. But there's no need to use native SQL for the above query. As you can see, HQL is perfectly capable of expressing that query.
You can use SQL directly, via createNativeQuery, or register a new function as shown in this example to call it from HQL

How to make hql selects in spring-batch?

I want to use spring-batch for retrieving and processing data from a postgres db.
I have a working SQL statement that would give me the full result set (about 400k entries):
private static final String QUERY = "SELECT * FROM MyDataTable ";
Now I want to use the JpaPagingItemReader so that the data is fetched (and written elsewhere) in chunks:
JpaPagingItemReader<MyEntity> reader = new JpaPagingItemReader<>();
reader.setEntityManagerFactory(emf);
reader.setQueryString(QUERY);
But it does not work:
[] 2014-09-17 16:31:58,234 ERROR : QuerySyntaxException: unexpected token: * near line 1, column 8 [SELECT * FROM my_data_table]
I also tried SELECT FROM MyDataTable and SELECT m FROM MyDataTable m without the star. Same result.
So, how can I execute that hql query with spring-batch?
By the way: the query works fine in a sql editor like pgAdmin.
SELECT m FROM MyDataTable m is almost correct (it is valid JPQL query as long as you have entity calles MyDataTable). So, it seems that you don't have entity class named MyDataTable.
As JpaPagingItemReader#setQueryString(String) accepts JPQL queries you should make sure that you have entity class for this table and then you should use its name instead MyDataTable.
By the way - for HQL queries there's HibernatePagingItemReader.

JDBC query doesn't work when giving NamedParameterJdbcOperation gets date as parameter (in params map)

I try to query my Mysql DB using JDBC.
I use the org.springframework.jdbc.core.namedparam.NamedParameterJdbcOperations.
The column DATE_FROM in my_table is defined as DATE column (which is also a PK).
A simplified version of a query which works looks like this:
SELECT * FROM my_table WHERE DATE_FROM >='2015-03-01';
But then, I tried to change the the '2015-03-01' to be given as a named parameter. the query looked like this:
SELECT * FROM my_table WHERE DATE_FROM >=:fromDate;
while I invoked the NamedParameterJdbcOperations.update() like this:
map.put("fromTime", '2015-03-01');
namedParameterJdbcOperations.update(sql, map);
Although everything, to my understanding, remains the same, I get:
com.mysql.jdbc.MysqlDataTruncation: Data truncation: Incorrect date value: ''2015-03-01'' for column 'MEASUREMENT_DATE' at row 1.
Does someone know why?
Did you realize that you named the placeholder in the SQL "fromDate" and in the map, you named it "fromTime"?

jOOQ problems with limit..offset - no values sets

I am trying to build a query using jOOQ, this is my test code:
DSLContext create = DSL.using(SQLDialect.DERBY);
String query = create.select().from(TABLE).limit(1).offset(0).getSQL()
I get as query:
select field1, field2...fieldN etc from TABLE offset ? rows fetch next ? rows only
the problem is ? in ? rows fetch next ? rows only it seems to ignore the values that i used in limit and offset to build the query, why?
I am trying to select the first row from the results and I am using jooq 3.4.1
Thanks for the help
Query.getSQL() returns your SQL string with ? as placeholders for your bind variables. The idea is that you can feed this statement to a PreparedStatement and then explicitly bind all variables, which are available through Query.getBindValues().
You can also have jOOQ inline all your bind variables, by calling Query.getSQL(ParamType) as such:
String sql = query.getSQL(ParamType.INLINED);

Saying position beyond number of declared ordinal parameters

I want to perform a native/raw mysql query using hibernate, I have this:
sessionFactory.getCurrentSession().createSQLQuery(
"update table1 set someCounter = someCounter + 1 where id = ?")
.setParameter(1, someId)
.executeUpdate();
I'm getting the error:
threw exception [Request processing failed; nested exception is
org.hibernate.QueryParameterException: Position beyond number of declared ordinal
parameters. Remember that ordinal parameters are 1-based! Position: 2]
with root cause
org.hibernate.QueryParameterException: Position beyond number of declared ordinal
parameters. Remember that ordinal parameters are 1-based! Position: 2
What's wrong here?
Use index as 0 since the parameter index start from 0.
sessionFactory.getCurrentSession()
.createSQLQuery("update table1 set someCounter = someCounter + 1 where id = ?")
.setParameter(0, someId)
.executeUpdate();
Since you are using Hibernate, you can use the named parameter as well i.e.
sessionFactory.getCurrentSession()
.createSQLQuery("update table1 set someCounter = someCounter + 1 where id = :id")
.setParameter("id", someId)
.executeUpdate();
The parameters use a zero based index. Try:
sessionFactory.getCurrentSession().createSQLQuery("update table1 set someCounter = someCounter + 1 where id = ?")
.setParameter(0, someId)
.executeUpdate();
The current Hibernate JavaDocs also specify that setPosition relies on zero based indexing for positional parameters. http://docs.jboss.org/hibernate/orm/4.1/javadocs/org/hibernate/Query.html#setParameter%28int,%20java.lang.Object%29
setParameter
Query setParameter(int position,
Object val)
throws HibernateException
Bind a value to a JDBC-style query parameter. The Hibernate type of the parameter is first detected via the usage/position in the query and if not sufficient secondly guessed from the class of the given object.
Parameters:
position - the position of the parameter in the query string, numbered from 0.
val - the non-null parameter value
Throws:
HibernateException - if no type could be determined
Check the out the parameters section of this document: https://access.redhat.com/knowledge/docs/en-US/JBoss_Enterprise_Web_Server/1.0/html/Hibernate_Core_Reference_Guide/querysql.html#id3043464
There has been some discussion regarding whether the setParameter() method is zero based or one based. This confusion is due to the exception received by the poster noting that parameters are 1 based, while the JavaDoc states that they are zero based. I analyzed the Hibernate source code and believe that they are in fact zero based. Assuming that I checked the right class, the underlying code uses a list to store the parameter bind values, which would imply that the setParameter method is in fact zero based. Checkout the source code for yourself: https://github.com/hibernate/hibernate-orm/blob/master/hibernate-core/src/main/java/org/hibernate/internal/AbstractQueryImpl.java
Positional parameters start from 0 not 1
Native SQL queries support positional as well as named parameters:
update your query by passing 0 instead of 1 in setParameter(1, someId)
sessionFactory.getCurrentSession().createSQLQuery("update table1 set someCounter = someCounter + 1 where id = ?")
.setParameter(0, someId)
.executeUpdate();
resource parameters
To those of you who couldn't resolve based on the solution above, it seems like at times hibernate (depending on the version, I'm using 3) actually gives you the wrong error, for example the issue could be present if you make a syntax error in the hibernate q language:
find("from Student s where s.id = :id")
change it to this:
find("from Student s where s.id = ?")
actually resolved that issue. I guess my main point is that you should also look at your syntax for the issue bc it seems hibernate can incorrectly label this exception.

Categories

Resources