How do I use custom SQL in sprint data repository? - spring-boot

I`m using Repository like this:
public interface UserRepository extends Repository<User, Long> {
List<User> findByEmailAddressAndLastname(String emailAddress, String lastname);
}
But what I need is execute my own sql statement.
select u.* from users u where exists ( select 1 from expires_users where users_id = u.id )
Please, past link references in answers.

I think you can do as pointed in the documentation of Spring Data JPA.
Here is an example:
public interface UserRepository extends JpaRepository<User, Long> {
#Query("select u.* from User u
where exists(select 1 from ExpiredUser e where e.id = u.id)")
Page<User> findExpiredUsers(Pageable pageable);
}
The Page and Pageable parts are for paging results, assuming that this query could return many more results than you would like to process at once. More information on paging results can be found here.

Related

How to get payload display as below? I wanted to join multiple roles access into one array(Native Query) as shown in the second example

I a intern student,I tried join table use native query (user, role ,access)it success but when I use get mapping to display role_name and access by email, the payload display not like I want.
Payload when I get by email,I don't display like this. Example 1
Payload I want to get. I want to be display like this. Example 2
Here is my code:
UserRepository.java
#Repository
public interface UserRepository extends JpaRepository<User, Long> {
#Query(value = "SELECT users.name, users.email, role.role_name, access.acc_name FROM users LEFT JOIN user_role ON user_role.user_id = users.id LEFT JOIN role ON role.rid = user_role.role_id LEFT JOIN role_access ON role_access.role_id = role.rid LEFT JOIN access ON role_access.access_id = access.id WHERE users.email= :email", nativeQuery = true)
List<Map<String, Object>> findUserByRoleIdByAccessById(#Param("email") String email);
}
--
UserController.java
#GetMapping("/users/access/{email}")
public List<Map<String, Object>> getuserAccess(#PathVariable(value = "email") String email) {
return userRepository.findUserByRoleIdByAccessById(email);
}

JPA Custom query Delete from multiple tables

I have an custom query for delete records from 2 tables as follows
#Repository
public interface RoamingStatusHistoryRepository extends JpaRepository<RoamingStatusHistory, String> {
#Query("DELETE rsh,rs from RoamingStatusHistory rsh inner join RoamingStatus rs on rsh.msisdn = rs.msisdn where TIMEDIFF(NOW(),rsh.createdDate)>'00:00:30'")
public List<Date> deleteByDate();
}
But after DELETE IntelliJ saying from expected got rsh and after rsh there is a error saying alias definition or WHERE expected, got ','
How to fix this issue. Have researched in the internet but couldn't find a solution
I assume that this query is a native SQL query so you have to add nativeQuery = true
#Repository
public interface RoamingStatusHistoryRepository extends JpaRepository<RoamingStatusHistory, String> {
#Query("DELETE rsh,rs from RoamingStatusHistory rsh inner join RoamingStatus rs on rsh.msisdn = rs.msisdn where TIMEDIFF(NOW(),rsh.createdDate)>'00:00:30'",
nativeQuery = true)
public List<Date> deleteByDate();
}

When using CrudRepository how can I use transformers

I have read this article
https://smarterco.de/spring-data-jpa-query-result-to-dto/
And tried this.
#Repository
public interface UserRepository extends JpaRepository<User, Long> {
#Query("SELECT u FROM User AS u")
List<User> findAll();
#Query("SELECT new de.smarterco.example.dto.UserNameDTO(u.id, u.name) FROM User u WHERE u.name = :name")
List<UserNameDTO> retrieveUsernameAsDTO(#Param("name") String name);
}
And it works.
But lets say my User had a list of Address. And my UserNameDTO also had a corresponding dto. How could I do that?
Can I somehow attach a resultTransformer to the query? or register a converter?
Looking forward to your suggestions.
Best regards. Ole Bille

select distinct values using spring data rest

I'm using java 8 and spring-data-rest to create API on my data.
I have a table Car(id, name, date...)
I'm trying to have an endpoint to retrieve distinct car names.
here's my Repository :
#RepositoryRestResource(path = "cars")
public interface CarRepository extends JpaRepository<Car, Long> {
//What i want to do
//#Query(value = "select distinct c.name as name from Car c")
#Query(value = "select distinct c from Car c")
List<Car> findDistinctName();
}
The query commented does not work , i have an exception
java.lang.IllegalArgumentException: PersistentEntity must not be null!
apparently this is the normal behavior of SDR.
I tried another solution by using Projections
#Projection(name = "name", types = {Car.class})
public interface CarName {
String getName();
}
but i cant get the distinct values, any idea?
Thank you :)
All you need, to do if you need a distinct list of cars, is such this query method:
public interface CarRepository extends JpaRepository<Car, Long> {
List<Car> findDistinctBy();
}
Spring Data JPA supports the Distinct keyword in repository query methods to set a distinct flag on the query to be created.
I found an (ugly) workaround, using jpql :
#Query(value = "select c from Car C WHERE c.id IN (SELECT min(ca.id) FROM Car ca Group by ca.name)")
I think you should remove the #Query annotation.
Just
List<Car> findDistinctName(); or List<Car> findNameDistinct(); should suffice.
It will automatically generate the query select c.name from Car c

JPA #Query annotation does not seem to be using paramter

I have a Spring Boot application using JPA/Hibernate as entity management/modeling. I have the following user class:
#Entity
public class User {
#Id
private Long Id;
private String name;
//more fields, getters and setters below
}
I want users of my application to be able to search for users by name. So in my repository interface, I have:
public interface UserRepository extends JpaRepository<User, Long> {
#Query(value = "SELECT u from User u WHERE lower(u.name) LIKE lower(:name)")
List<User> findByNameLike(#Param(value="name") String nmae);
}
Then in my UserController, I have:
#GetMapping(value = "/users/")
public #ResponseBody List<User> search(#RequestParam String name) {
return this.userRepository.findByNameLike(name);
}
This always returns an empty list. I know the name parameter is coming in correctly.
Moreover, I do know that it is recognizing the #Query annotation, because if I change the query to something like
SELECT u FROM User u
it will return me all users. Or if I change it to
SELECT u from User u WHERE u.name = '%Bob%'
and remove the parameter from the method, it will return all users whose name is Bob. I've tried other variations of the query, such as
SELECT u FROM User u WHERE lower(u.name) LIKE CONCAT('%', lower(:name), '%')
SELECT u FROM User u WHERE u.name = :name (even a simple equals doesn't work)
and so on and so forth. Every source I look at whose syntax I copy seems to say I'm writing the query right, so I think something else must be going on.
I've also tried letting Spring generate the query for me, using
public List<User> findByNameLike(String name);
public List<User> findByNameContaining(String name);
which also don't seem to work. Any help would be appreciated here!

Resources