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

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

Related

how to use pg_column_size in hibernate?

I am trying to get the size of a row in a postgresql table, I found that pg_column_size would do the trick, but its not working with hibernate :
#Query("SELECT pg_column_size(t.*) as filesize FROM TABLE as t where name=:name")
int getSize(#Param("name") String name);
intellij is giving this error :
< operator > or AS expected, got '('
I guess the problem is that hibernate doesnt support specific postgresql queries, it only supports the basic sql queries.
so is there a way around this ? if not is there a way to get/estimate the size of a postgresql row in java ?
In order to use a built-in postgres function , you have to declare you JPA query as nativeQuery
you should first change query to native (hibernate will directly execute the query instead of jpa -> sql generation )
#Query(value="SELECT pg_column_size(t.*) as filesize FROM TABLE as t where name=:name",nativeQuery=true)
int getSize(#Param("name") String name);
Also be sur of the TABLE name to be correct .
Add nativeQuery = true after the native query.
#Query("SELECT pg_column_size(t.*) as filesize FROM users as t where t.name=:name",nativeQuery = true)
use above Query, Hope This will work.

Passing entire where clause to native spring jpa #Query [duplicate]

This question already has answers here:
Dynamic spring data jpa repository query with arbitrary AND clauses
(4 answers)
Closed 3 years ago.
Currently I'm unable to know the fields that will be within the SQL where clause (think adhoc) when creating the native SQL in my spring #Query. Therefore I'm passing in the entire where clause.
If I output the SQL to the console and paste it in to my sql editor I'm able to receive a valid resultset.
SELECT * FROM lorder WHERE order_id = 1196077
Last SQL output to the console was:
Hibernate:
/* dynamic native SQL query */ SELECT
*
FROM
lorder
WHERE
?
and the where clause value being passed in to the #query is:
order_id = 1196077
This is what I am currently doing which is not working.
#Query(
value = "SELECT * FROM lorder WHERE :where",
nativeQuery = true)
List<OrderEntity> listSelected(#Param("where") String where);
Not sure if passing the entire where clause is possible but I'm expecting a list. However I'm currently getting an empty collection.
Since using the #Query annotation you can only use named parameters (your :where) or ordinal parameters (e.g. ?1, ?2) of a specific Java-type, it's not possible to inject partial SQL-expressions.
However you could use a TypedQuery to add partial SQL to a query:
public List<OrderEntity> getOrdersUsingWhereClause(EntityManager em, String whereClause) {
TypedQuery<OrderEntity> query = em.createQuery(
"SELECT o FROM lorders o WHERE " + whereClause,
OrderEntity.class);
return query.getResultList();
}
See https://www.objectdb.com/java/jpa/query/parameter#Parameters_vs.Literals
The JPA's criteria query gives you more power to control where clause along with many other supported functionalities.
List of functions : https://en.wikibooks.org/wiki/Java_Persistence/Criteria
Criteria Queries : https://www.baeldung.com/hibernate-criteria-queries
Learn more about criteria query and criteria builder here

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.

Slow performance on Hibernate + Java but fast when I use TOAD with the same native Oracle query

I've detected a performance problem with hibernate and native queries on Oracle. When I execute a complex SQL query with several parameters on TOAD I get the result in miliseconds. However, when I execute the same query using Hibernate this time is incremented hugely (up to four seconds or even more).
My SQL query is rather complex, return an unique value (so, the problem is not related with the time necessary to instation classes) and it contains several parameters with the the format ':nameParameter'. This query is stored in a String. For example,
String myNamedNativeQuery = "select count(*) from tables "+
"where column1 = :nameParameter1 "+
"and column2 = :nameParameter2";
//actually my sentence is much more complex!!
When I execute the sentence on TOAD it is resolved in few miliseconds. But using this sentence with Hibernate
SQLQuery query = session.createSQLQuery("myNamedNativeQuery");
query.setParameter(nameParameter1, value1);
query.setParameter(nameParameter2, value2);
query.uniqueResult();
are necessary several seconds to get the same result.
I realized if I replaced the parameters directly on the native query and then I execute the sentence using Hibernate the time decreases drastically. It would be something like that:
String strQuery = session.getNamedQuery("myNamedNativeQuery").getQueryString();
myNamedNativeQuery = myNamedNativeQuery.replace("nameParameter1", value1);
myNamedNativeQuery = myNamedNativeQuery.replace("nameParameter2", value2);
SQLQuery query = session.createSQLQuery("myNamedNativeQuery");
query.uniqueResult();
Anybody knows what's happening??
Thanks in advance.
PS: The Oracle version is 9i and Hibernate 3.2
I think what's happening with this code :
SQLQuery query = session.createSQLQuery("myNamedNativeQuery");
query.setParameter(nameParameter1, value1);
query.setParameter(nameParameter2, value2);
query.uniqueResult();
is this:
at line 1 : a query plan is created based on some expected values for your named parameters.
at line 4 : the query is executed with value1 and value2, but those values are not "good values" for the query plan that was elaborate at line 1 and so, the database is executing a very inappropriate plan for the actual values and it takes a lot of time.
Why ?
Looking at the source code of HibernateSessionImpl.createSQLQuery(...) I found this line of code:
SQLQueryImpl query = new SQLQueryImpl(
sql,
this,
factory.getQueryPlanCache().getSQLParameterMetadata( sql )
);
which is calling getQueryPlanCache() with some parameterMetaData. I assume that this metadata is not good enough.
My answer to you is:
Remove all bind parameters and use StatelessSession instead of Session
Use SQLQuery instead of query with full SQL including parameter values
StatelessSession session = sessionFactory.openStatelessSession();
I had similar problem and till I get better solution,this is what I managed to make it work.
See Hibernate parameterized sql query slow and active oracle sessions
<property name = "hibernate.temp.use_jdbc_metadata_defaults">false</property>
Add this to your hibernate.cfg.xml or update your application properties file.

jpa select statement with subnets

I am trying to write query with multiple select subnets in it.But I defined a nativequery
I am giving error. Compiler specifies that "(" after "from" is not proper. How can I define
a native query in JPA 2.0
For eaxmple:
SELECT *
from (SELECT ****C) REI3 where column1 != 1
GROUP BY REI3.column2 order by REI3.column3 ASC
JPA does not have too much to do with validating SQL syntax, query is passed to JDBC driver. Likely you are trying run query such a way, that it is interpreted as JP QL. Instead try following method to execute it as
Query q = em.createNativeQuery("Your SQL here");
Other alternative is to use NamedNativeQuery Example

Categories

Resources