Выборка из трёх связанных таблиц

144
16 сентября 2021, 01:30

Есть 3 таблицы (postgreSQL):

@Entity
@Table(name = "application", schema = "applications")
public class Application implements Serializable {
    @Id
    @GeneratedValue
    @Column(name = "application_id")
    private long applicationId;
    @Column(length = 400)
    @Size(min=50, max=400)
    private String applicationDescribing;
    @ManyToOne(fetch = FetchType.EAGER)
    @JoinColumn(name = "customerId")
    private Customer Customer;
    .....

Далее есть абстрактный класс User, от которого наследуется класс Customer, который имеет отдельную таблицу в БД.

@Entity
@Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)
public abstract class User implements Serializable {
    @Id
    @GeneratedValue(strategy = GenerationType.TABLE)
    private Long userId;
    @ManyToOne(fetch = FetchType.EAGER)
    @JoinColumn(name = "localitiesId")
    private Localities userLocality;
    .....
@Entity
@AttributeOverride(name="userId", column=@Column(name="customerId"))
public class Customer extends User {
    @Column(length = 8)
    private String userType;
    .....

У User и, соответственно, Customer есть поле Locality - отдельный класс, связь many to one.

@Entity
@Table(name = "localities", schema = "resource")
public class Localities implements Serializable {
    @Id
    @GeneratedValue
    @Column(name = "id")
    private long localitiesId;
    @Column(name = "region", length = 50)
    private String region;
    ....

Пробую реализовать поиск по Application, где будет задана фраза (String) keyWord и locality_id (long) locality. Этот вариант не находит userLocality в Application (хотя код компилируется):

 @Query(value = "SELECT u FROM Application u WHERE u.applicationDescribing LIKE %:keyWord% " +
            "AND userLocality IN (SELECT c FROM User c WHERE c.userLocality IN " +
            "(SELECT l FROM Localities l WHERE l.localitiesId = :locality))")
List<Application> getApplicationsByKeyWordsAndRegion(@Param("keyWord") String keyWord, @Param("locality") long locality);

Пробовал и такой вариант (Ошибка. Caused by: o.h.h.i.a.QuerySyntaxException: Path expected for join!):

@Query(value = "SELECT a FROM Application a " +
    "JOIN Customer c ON a.customerid = c.userid " +
    "JOIN Localities L ON c.localitiesid = L.id " +
    "WHERE a.applicationDescribing LIKE %:keyWord% AND L.id = :locality")
List<Application> getApplicationsByKeyWordsAndRegion(@Param("keyWord") String keyWord, @Param("locality") long locality);

Оба не работают. Подскажите как сформировать правильно запрос чтобы получить на выходе List <Application>, который отвечает ключевому слову keyWord и заданному региону locality.

Answer 1

В 1 запросе %:keyWord% не сработает скорее всего, нужно параметр keyWord передавать уже с %, либо еще видел такое -LIKE CONCAT('%',:keyWord,'%')

Во 2 - JOIN .. ON .. не работает c JPQL, точнее ON не нужен, запрос должен быть что-то вроде :

 SELECT app FROM Application app
 INNER JOIN app.Customer customer
 INNER JOIN customer.userLocality locality
 WHERE
 locality.localitiesId = :locality
 AND app.applicationDescribing LIKE CONCAT('%',:keyWord,'%')

Еще момент с private Customer Customer; в Application, имена полей по соглашению должны быть с маленькой буквы, не уверен, что это могло повлиять, но все же.

READ ALSO
Данные MutableLiveData из Spinner возвращают null

Данные MutableLiveData из Spinner возвращают null

Я использую паттерн MVVM и DataBinding в своём проектеПередать значения в Spinner мне удалось, но вот получить из оттуда - проблема

176
как из url вырезать mail и токен на js без регулярки?

как из url вырезать mail и токен на js без регулярки?

например в переменную mail="gogglepost@gmailcom" и token="$23y$113$px/m3Gi54234dgdfd2m1

167