1

Is it possible to invoke parameter's method inside @Query annotation?

Example:

@Query("SELECT user " +
    "FROM User user " +
    "WHERE (?1.getFilter() = '*' OR user.name = ?1)");
List<User> getUsers(UserNameFilter userNameFilter);

I know that I can do something like this:

@Query("SELECT user " +
    "FROM User user " +
    "WHERE (?1 = '*' OR user.name = ?1)");
List<User> getUsers(String userName);

But when a number of filters are increasing it means that I need to change a number of parameters.

ByeBye
  • 6,650
  • 5
  • 30
  • 63

1 Answers1

12

With SpEL you can use Spring bean methods in your queries, for example

@Query("select e from MyEntity e where ?#{@myBean.myMethod(#param1)} is true")
List<MyEntity> entities = getEntity(@Param("param1") String param);

You can define your bean in any proper way, for example:

@Component
public class MyBean {
    public boolean myMethod(String param) {...}
}

Or it can be even the same repo:

public interface MyRepo extends JpaRepository<MyEntity, Long> {

    @Query("select e from MyEntity e where ?#{@myRepo.myMethod(#param1)} is true")
    List<MyEntity> entities = getEntity(@Param("param1") String param);

    default boolean myMethod(String param) {...}
}

Also you can use parameter properties in your queries:

@Query("select u from User u where u.firstname = ?#{#customer.firstname}")
List<User> findUsersByCustomersFirstname(@Param("customer") Customer customer);

Additional info: 1, 2, 3

Cepr0
  • 28,144
  • 8
  • 75
  • 101
  • Is this even possible for Spring JPA query IN ? For instance `select u from User u where u.firstName IN (?#{#customer.firstname})` ? – mrkernelpanic Nov 26 '19 at 12:41
  • @mrkernelpanic Why not? Have you tried it?.. I can't find such in Spring Data JPA project [examples](https://github.com/spring-projects/spring-data-jpa/blob/master/src/test/java/org/springframework/data/jpa/repository/sample/UserRepository.java) but I'm sure that this should work.. – Cepr0 Nov 26 '19 at 14:23
  • 1
    It works but slightly different. You have to change to `select u from User u where u.firstName IN (:#{#customers.![firstName]} )` where `customers` can be a List of Objects. – mrkernelpanic Nov 27 '19 at 09:59