spring data compose #query query dynamically - java

I have situation in which I have to compose a JPQL query in some method, then pass this query to spring data query method to be used as the query in #Query annotation
#Query(value = ":DyanamicQuery")
List<PrizeInsuranceConfiguration> filterConfigurPrizeInsurance(String DyanamicQuery);
or at least the conditions part
#Query(value = "SELECT c FROM PrizeInsuranceConfiguration c WHERE :DyanamicConditions")
List<PrizeInsuranceConfiguration> filterConfigurPrizeInsurance(String DyanamicConditions);

Do, you can do that. There are two reasons why not:
sql injection (spring data work with prepared statements);
(result of first reasone) spring data create query tree and bind all params
But if you need dynamic query you can use Specifications, Query by Example or Querydsl.

Related

How to use CTE expression WITH clause in Spring Data JPA

I want to write a recursive query in SQL Server. So I am using CTE. Query is working properly in SSMS but when I am trying to use the same CTE in JPA as native SQL it gives an error:
Invalid name column Id.
The entity (which I am using in CTE to fetch data recursively) has #Id #Column(name="pk_id") private int Id field.
I also followed this SOQ : cte sql to simple subset query for JPA
But still getting error as invalid name column Id.
I have never used CTE before. How can this be fixed?
You can write the SQL query in JPA Repositories since the #Query annotation takes native query as well. For that, you need to specify the SQL query in the value parameter and nativeQuery is true as follow.
You can write CTE queries as well.
public interface ISomeRepository extends JpaRepository<Entity, Long> {
#Query(value = "SQL QUERY NEED TO BE WRITTEN HERE", nativeQuery = true)
List<Long> getEntityIds();
}

HQL Query inside spring #Query annotation

I have been trying to understand the difference between HQL and JPQL. The hibernate documentation at here
suggest that writing select is necessary for JPQL but not in HQL. But when I try writing HQL or JPQL inside Query annotation of spring data JPA , both HQL and JPQL works .
import java.util.List;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.CrudRepository;
public interface UserRepository extends CrudRepository<User, Long> {
#Query(value = "from com.demo.spring.data.jpa.User u")
public List<User> findAllUsersHQL();
#Query(value = "select u from com.demo.spring.data.jpa.User u")
public List<User> findAllUsersJPQL();
}
My understanding is since the Query annotation is intended for JPA why is HQL supported ?
Or let me put in other words -
Can we write HQL in the Query annotation - Does spring data JPA supports both ?
I think it depends on which JPA impleemntation you use.
Even though Spring data says it supports JPQL, Spring data in itself isnt implememnting any functionality for validating and implementing queries with JPQL.
Spring will rely on underlying JPA impleemntation that will validate and convert given JPQL queries into plain SQL.
If the underlying adapter is a hibernate Adapter, There are fair chances that it will support HQL and will not limit the application to JPQL.
Moreover, as jdicker mentioned above, JPQL is a subset of HQL, or in the other words, hibernate provided mucm more functionalty than that of JPA.. so you shoudl be able to parse HQL in spring data as long as you are using Hibernate sa an underlying JPA engine.
DIY - You can try putting a breakpoint in QueryTranslatorImpl and confirm the behavior yourself.

Difference between hibernate query api and criteria api [duplicate]

Can anyone please tell me the difference between Hibernate's:
createCriteria
createQuery
createSQLQuery
Can anyone tell me what data these three functions return, c.q. direct me to a proper and simple link to study these Hibernate functions?
To create query in the Hibernate ORM framework, there is three different types. The following are the three ways to create query instance:
session.createQuery()
session.createSQLQuery()
session.createCriteria()
Look into the details of each category in detail.
Session.createQuery()
The method createQuery() creates Query object using the HQL syntax. For example:
Query query = session.createQuery("from Student s where s.name like 'k%'");
Session.createSQLQuery()
The method createSQLQuery() creates Query object using the native SQL syntax. For example:
Query query = session.createSQLQuery("Select * from Student");
Session.createCriteria()
The method createCriteria() creates Criteria object for setting the query parameters. This is more useful feature for those who don't want to write the query in hand. You can specify any type of complicated syntax using the Criteria API.
Criteria criteria = session.createCriteria(Student.class);
1. session.createQuery()-> Can create query using HQL and can perform CRUD Operations
Example:
Query query = session.createQuery("from Student");
List list=quey.list();
Query query = session.createQuery("update Student where studentid=9");
int result=query.executeUpdate();
Query query = session.createQuery("delete Student where studentid="+ studentId);
int result=query.executeUpdate();
Query query = session.createQuery("insert into Student where studentid="+ studentId);
int result=query.executeUpdate();
session.createSQLQuery()-> Can create query using SQL and can perform CRUD Operations
session.createCriteria()->Can create query using Criteria API and can perform only Read Operations
------------------------
PERSON
------------------------
**DB_Column**| **POJO**
PERSON_ID | personID
------------------------
createQuery()
you are using pojo fields. Using HQL syntax.
Query query = session.createQuery("from Person s where s.personID like 'A%'");
// returns:
List<Person> persons = query.list();
createSQLQuery()
You are using Native|DB fields.
After googling some site, Came to know this will also clear the cache as hibernate don't know the what you have executed.
Query query = session.createSQLQuery("select s.* from Person s where s.person_ID like 'A%'");
// returns:
List<Object[]> persons = query.list();.
createCriteria()
Create sql query using Criteria object for setting the query
parameters.
Useful when switching DB.
Read only query
Criteria criteria = session.createCriteria(Person.class);
criteria.add(Restrictions.like("personId", "A%"));
List<Person> persons = criteria .list();
createSQLQuery -- is for native sql querying which is selected by you with jdbc driver cfg or something else.
createQuery -- is for hibernate querying which provides you independent querying which makes you run that on many databases using API and more other advantages.
createCriteria -- is better to use for simple querying on db because of it's simplicity.
I hope this helps you!

Hibernate query build

Currently i am using the CreateSQLQuery query model to read the data from database using HIbernate. Now, I want to modify my query by using either HQL or Hibernate Criteria. My query looks like as follows.
select concat(d.AREA,' ',d.CITY) as location, a.TRANSFERRED_DATE as ActualTransferDate, concat(c.SCAN_CODE,',',c.SERIAL_NO) as ScanserialCode, c.MODEL_NO as ModelNum, c.ASSET_NAME as AssetName from table_transfer a, table_category b, table_asset c, table_location d where a.ASSET_ID = c.ASSET_ID and b.ASSET_CATEGORY_ID = c.ASSET_CATEGORY_ID and a.TRANSFER_TO_LOCATION=d.LOCATION_ID"
I am not sure how can i can convert this to Hibernate SQL or Criterion based query. Can any one help me?
You can introduce the fields for location and scanserialCode in your entity and mark them as #Formula
e.g.
#Formula("concat(d.AREA,' ',d.CITY)")
private String location;
See an example here or here
Then use join and where in HQL or Hibernate Criteria

Putting external properties into named queries

Does anyone know of a way, if any, to put an external property into a jpa named query?
So for example:
#NamedQuery(name = "Test", query = "select t from ${table.name} t")
As opposed to:
#NamedQuery(name = "Test", query = "select t from TableName t")
Thanks
Annotations are final hence they cannot be changed at runtime, so you cannot do that.
You could define the native query at runtime instead of as a named query and translate the SQL string yourself.
Other solution would be to use some sort of pre compiler on your code, or use some sort of persistence unit event to post process your queries. If you are using EclipseLink, you could use a SessionCustomizer for this, or a SessionEventListener to pre process SQL queries before they are executed.

Categories

Resources