jpa select statement with subnets - java

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

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

Avoid SQL Injection in Spring JPA

I am using sql query like
String query = "Select max(case when UPPER(key)='firstname' then value end) as firstNameName, , ... order by "+orderBy;
result = em.createNativeQuery(query).getResultList();
em.close();
for some reason i would have to use dynamic +orderBy . Where orderBy =firstname ASC , lastname DESC etc. Tried using .setParameter(1, orderedBy) but in this case i am not getting expected ordered results.
For avoiding sql injection threats you firstly need to remove appending parameters to your query. When you're appending parameters in your app, the atacker can hijack your sql code (with apostrophes and other means for example)
For example:
If your query is "select * from table where name="+id
The attacker can pass to the field values such as:
'John' or 1=1; ->sees all your records in this table
Or even
'John' or 1=1;Delete all from users;' -> deleting all entries from users table.
Hijacking queries can be avoided via mechanisms such as input sanitization, input whitelisting/blacklisting(removing unwanted characters from the input/ defining a list of allowed or unnalowed characters). Most modern framerowks such as JDBC/JPA/Hibernate can offer protection from this threat.
With all this stated we should take into consideration the following scenarios:
Considering sql where parameters:
JDBC for example offers prepared statements, where you define a variable in your sql, and the framework replaces it
In your case a JPA implementation(Hibernate) also has mechanisms for avoiding this threat, also via parameterized queries and positional paramaters:
via native query positional parameters:
Query q = em.createNativeQuery("SELECT count(*) FROM mytable where username = ?1");
q.setParameter(1, "test");
via named parameters(jplq)
Query q = em.createQuery("SELECT count(*) FROM mytable where username = :username");
q.setParameter("username", "test");
Considering orderBy parameters:
CriteriaQuery/spring Specifications
CriteriaBuilder cb = this.entityManager
.getCriteriaBuilder();
CriteriaQuery<RESULT> criteria = cb.createQuery(RESULT.class);
Root<RESULT> root = criteria.from(RESULT.class);
return this.entityManager.createQuery(
criteria.select(root).orderBy(cb.asc(root.get("ORDER_BY_FIELD"))))
.getResultList();
More on criteriaQueries usage and config here
Passing orderBy via spring specific Sort parameter built beforehand(using the spring-data library)
Sort sort = Sort.by(Sort.Direction.ASC, "criteria");
em.createQuery(QueryUtils.applySorting(yourSqlQuery_withoutSorting,sort));
annotate method with #Query with spring-data library:
You can achieve the same result with less boiler plate code(without injecting an entityManager and creating a nativeQuery) by just annotating a method with a #Query annotation:
#Query("select u from User u where u.lastname like ?1%")
List<User> findByAndSort(String lastname, Sort sort);
Note:
Native vs non-native(jpql):
JOQL queries are independent of the database vendor(MySQL,PostGres,Oracle,DB2), nativeQueries usages are more focused when you need to use a database specific functionalities which differes accross vendors.
For a brief example jpql can not support native [With]2 clause PLSQL standard functions
Regarding your edit:
You can try to apply the following sql trick for dynamic ordering:
SELECT param1, param2 ...
FROM ...
ORDER BY case when :sortParam='name asc' then name asc END
case when :sortParam='name desc' then name desc END
....
else 0

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

JPQL query containing LIKE converted into criteria

I need to use the LIKE operator into an JPA query. I need to use it for types other then String but the JPA criteria API allows me to add only String parameters. I tried using the .as(String.class) but something fails and also tried calling the CAST function from the underlying Oracle that again fails for unknown reasons to me.
I tried writing the query also in JPQL and it works as expected. This is the query:
SELECT p from CustomerOrder p where p.id like '%62%'
UPDATE:
The query must be built in a generic fashion as it is for filtering, so it needs to be created at runtime. On the query that is already created I tried to add the LIKE clause like this:
query.where(builder.like(selectAttributePath.as(String.class), "%"+filterValue.toString().toLowerCase()+"%"));
But this crashes with this exception:
org.hibernate.hql.internal.ast.QuerySyntaxException: expecting CLOSE, found '(' near line 1, column 156 [select distinct generatedAlias0.id from de.brueckner.mms.proddetailschedact.data.CustomerOrder as generatedAlias0 where cast(generatedAlias0.id as varchar2(255 char)) like :param0]
I executed the same query directly to Oracle using SQLDeveloper, so it should be sound from this point of view. So the problem is the Hibernate is the issue. Any suggestions on how to fix it?
How can I write this query using JPA Criteria?
I fixed the problem by invoking the 'TO_CHAR' function from the underlying Oracle DB and using the LIKE operator like for normal String's.
query.where(builder.like(selectAttributePath.as(String.class), "%" +filterValue.toString().toLowerCase() + "%")
You can try the below code, it might require modifications.
CriteriaBuilder cb = em.getCriteriaBuilder();
CriteriaQuery<CustomerOrder> cq = cb.createQuery(CustomerOrder.class);
Root<CustomerOrder> order = cq.from(CustomerOrder.class);
cq.where(cb.like(Long.valueOf(order.get(CustomerOrder_.id)).toString(), "%62%"));
TypedQuery<CustomerOrder> q = em.createQuery(cq);
List<CustomerOrder> results = q.getResultList();

Does Hibernate HQL support aliasing subqueries?

I'm using Hibernate 3.2.6 and I'm attempting to make a query like so:
select
a,
(select min(date) as someAlias from B b where a.id = b.id)
from A a
where someAlias is not null and someAlias between :start and :end
Imagine that this query makes sense in the context that I'm operating in. When I run this query, I get an error saying "Unknown column 'someAlias' in 'where clause'". When I show the SQL output, I see that SQL doesn't seem to include the 'as someAlias' part of the query.
Is this just unsupported, or am I missing something? Or this just a feature not supported in version of Hibernate?
Translate the query to native sql and fire it on db, it will not work.It is not a valid query because aliases in select clause will not be visible in where clause.
Aliases are supported in HQL.

Categories

Resources