SQL запрос по списку параметров (Spring Data)

129
13 августа 2019, 22:20

Необходимо найти в БД (Postgres) всех юзеров или операторов (role) по списку регионов (List regions)

@GetMapping(value = "users-ext/findUsersByRegions/{role}")
@Timed
public ResponseEntity<List<UserDto>> findUsersByRegions(@PathVariable String role, @RequestBody List<String> regions}
...

Проблема заключается в том, что не получается составить правильный запрос по этим параметрам, типа List<User> findByRegionsAndAuthoritiesName(List<String> region, String role);

User.java
....
@Column(name = "region")
private String region;
....
@ManyToMany(cascade = CascadeType.ALL, fetch = FetchType.EAGER)
@JoinTable(
    name = "jhi_user_authority",
    joinColumns = {@JoinColumn(name = "user_id", referencedColumnName = "id")},
    inverseJoinColumns = {@JoinColumn(name = "authority_name", referencedColumnName = "name")})
@Cache(usage = CacheConcurrencyStrategy.NONSTRICT_READ_WRITE)
private Set<Authority> authorities = new HashSet<>();
....

Найти по отдельности не проблема

public interface UserRepository extends JpaRepository<User, Long>, JpaSpecificationExecutor{
List<User> findByAuthoritiesName(String role); // по роли
@Query(value = "select distinct user from User user join fetch user.authorities where user.region in (:regions)")
List<User> findAllByRegions(@Param("regions") List<String> regions); // по регионам
List<User> findByRegionAndAuthoritiesName(String region, String role); // по одному региону и одной роли
....

Последний вариант как по мне малооптимальный, так как предполагает стучаться в БД в зависимости от количества регионов, а потом создавать отдельный список и копировать данные с каждой итерацией.

В документации необходимого ответа не нашел (может быть пропустил или не недопонял, сорри) Кто-то сталкивался с подобным и может подсказать рабочий вариант запроса?

UP! после ответа уважаемого Nick

в моем случае работает

select * from jhi_user u where exists (select * from jhi_user_authority ua where ua.user_id = u.id and ua.authority_name ='ROLE_OPERATOR') and u.region in ('r10'); подставляя значения, но увы только в консоли.

jhi_user_authority //промежуточная таблица с полями user_id и authority_name
jhi_authority // java класс с одним полем name (ROLE_ADMIN, ROLE_USER, ROLE_OPERATOR)
@Entity
@Table(name = "jhi_authority")
public class Authority implements Serializable {
@NotNull
@Size(min = 0, max = 50)
@Id
@Column(length = 50)
private String name;
....

Помогите написать для UserRepository @Query

PS Прошу ногами не пинать, проект достался в наследство, плохо владею spring data, но я стараюсь)

Answer 1
@Query("select u from User u where " +
        "exists (select a from Authority a where a.user = u and a.name = :role) " +
        "and u.region in :regions")
List<User> findAllByRoleAndRegions(@Param("role") String role, @Param("regions") List<String> regions);
READ ALSO
Валидация аргументов командной строки JAVA

Валидация аргументов командной строки JAVA

Разрабатывается приложение командной строки, где строка следующего вида --file=dbtxt add --name=John --surname=Doe --age=27 --email=john@gmail

170
Jamod, детектировать изменение processImage \ детектировать наличие обмена

Jamod, детектировать изменение processImage \ детектировать наличие обмена

Создан Slave TCP Modbus при помощи библиотеки Jamod (пробовал так же j2mod с тем же результатом) согласно документацииРаботает, обмен идет, но есть пара...

97
@Query. QuerySyntaxException: Invalid path: &#39;b.userIP&#39;

@Query. QuerySyntaxException: Invalid path: 'b.userIP'

У меня есть запрос в SQLЗапрос работает

111
java.lang.StackOverflowError: stack size 8MB

java.lang.StackOverflowError: stack size 8MB

приложение для чтения новостей на котлинеиспользуется newsapi

113