How to implement CTE query via HQL in Java - java

I have written a MySQL query and I'm trying to implement via Hibernate. Please help us to resolve this. My MySQL CTE query:
WITH RECURSIVE employeeCte AS
(
select employee_id, employee_name, manager_id, 1 AS LEVEL from employee where employee_id = ?
union all
select e.employee_id, e.employee_name, e.manager_id, LEVEL + 1 from employee e join employeeCte m
on e.employee_id = m.manager_id
)
select * from employeeCte;
Hibernate code:
interface Employeerepository extends JpaRepository<Employee, String>{
#Query("above query")
List<Object> getEMployeeDetails(String employeeId);
}

CTEs are not yet supported in HQL, but I'm working on changing this for 6.0. In the meantime, you can use the native query approach as suggested by Mark Rotteveel, or you take a look at what Blaze-Persistence can do for you here, which supports CTEs and also comes with a Spring Data integration.

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();
}

How to make insert custom query in spring data jpa by using #Query annotation

I am using mssql and spring data JPA, I want to insert new records to a table by using custom #Query annotation.
public interface CustomerRepository extends JpaRepository<Customers, String>{
#Modifying
#Query("insert into Customers values (?1 , ?2)")
public void saveCutomer(int custId, Customer cust);
}
Its giving error,
Caused by: org.hibernate.hql.internal.ast.QuerySyntaxException: expecting OPEN, found 'values' near line 1, column 23 [insert into Customers values (?1 , ?2)]
I tried below also, same error.
#Modifying
#Query("insert into Customers select ?1 , ?2")
public void saveCutomer(int custId, Customer cust);
You don't do that using JPQL. You have batch DELETE and UPDATE but that's it.
Your options are:
1) Mark the query as native if you really make explicit insert (not recommended unless you intend to use some database-specific syntax not supported by JPQL.
2) Use standard save(Entity) method on your repository which is of course preferable.

Can #Query annotation in Spring Data JPA take in a list of enums?

I've been trying to figure out how to take an input of a list of enums for my sql query. This is what it looks like:
#Query(value = "Select * from employees where city in :cities", nativeQuery = true)
List<Employee> findByCities(#Param("cities") List<City> cities);
I understand that for simple queries we can rely on the JPA Criteria API but I want to know if I can actually do it this way instead. Because if so, i can create more complicated queries (such as joins with another table) if I could have this flexibility of specifying the list.
Yes spring-data-jpa's #Query can take a list of enums.
This is my repository method
#Query("Select u from User u where u.userType in :types")
List<User> findByType(#Param("types") List<UserType> types);
This is my repository call
userRepository.findByType(Arrays.asList(AppConstant.UserType.PRINCIPLE)))
And this is the query logs
SELECT user0_.id AS id1_12_,
user0_.date_created AS date_created2_12_,
...
...
FROM users user0_
WHERE user0_.user_type IN ( ? )
Hope this helps.
PS: I tested this in my local machine with positive results.
Update 1
The same doesn't work with nativeQuery=true. I tested it on my local system and it doesn't seem to be working with native queries. However with JPQL it works fine as mentioned in the above answer.
May be this answer will help.

Bulk update with HibernateTemplate and IN clause

I would like to perform a database bulk update using Spring's HibernateTemplate (Hibernate 5.1).
HibernateTemplate offers the following interface: public int bulkUpdate(String,Object...).
My query is UPDATE entity item SET item.attribute.id = ? WHERE item.id in (?.....?).
I had a lot of troubles and want to ask what is the proper way to use HibernateTemplate
The above query results in the deprecation warning [DEPRECATION] Encountered positional parameter near line 1, column 172 in HQ
Replacing the above query with JPA-style parameters (UPDATE entity item SET item.attribute.id = ?1 WHERE item.id in (?2,?3.....?N)) results in NullPointerException thrown by Hibernate when building parameter metadata
As seen on one of the most authoritative Hibernate sources, named parameters result in a misleading exception
Question is: how do I properly formulate a bulk update query using Spring's HibernateTemplate? As correctly reported by Mykong, HibernateTemplate automagically sets query parameters 0-based, but eventually the author got the program working with non-positional parameters without mentioning (or having at all) any warning.
I think that the recommended way to do that now a days is with Spring Data JPA. There is a getting started tutorial here.
So if you have an entity, you can add an interface that extends any of the reposiotry interfaces supported in SpringDataJpa and add a modifying query.
public interface CustomerRepository extends CrudRepository<Customer, Long> {
#Transactional
#Modifying
#Query("update Customer c set c.firstName = ?1 where c.id = ?2")
int updateNameById(String nameToUpdate, long id);
#Transactional
#Modifying
#Query("update Customer c set c.firstName = ?1 where c.id in (?2)")
int updateNameByIds(String nameToUpdate, List<Long> ids);
}
Then Spring will implement that method and you can use the it as:
customerRepo.updateNameByIds("newName", Arrays.asList(cust.getId()));
This will generate the following sql:
update customer set first_name=? where id in (?)
Here is the project I used to test with

Using Spring Data JPA, how can I create a query with multiple conditions ORed on same field?

I need help creating a JPQL query out of a native query having or condition along with other fields. Please lemme know if it is still not supported by JPA.
Sample Native Query :
select * from EMP where (EMP_FLAG is NULL or EMP_FLAG is 'Y') and EMP_ID in (1,2,3);
Now to use JPQL (Java Persistent Query Language) I have written following in-build query using source
findByEmpIdInAndEmpFlagIsNotNull(List<Long> ids);
But how to incorporate the check for EMP_FLAG = 'Y'?
Note** I do not intend to add a query using #Query annotation. (aware
of that solution)
Spring version : 4.2,
JAVA : 1.7
You can do like this
#Query("select e from EMP e where (e.empFlag is null of e.empFlag ='Y')and in :ids")
findByEmpIdIn(#Param("ids") List<Long> ids);
Choose the name you find the best for your method, and annotate it with
#Query("select e from Employee e where (e.empFlag is null of e.empFlag = 'Y') and e.empId in ?1")

Categories

Resources