Объединить таблицы в спецификации - PullRequest
0 голосов
/ 26 марта 2020

У меня есть 2 объекта.

@Entity
@Table(name = "T_LIFE_CYCLE_CUST_DETAIL_PARM")
@Data
public class ActionCriteriaParameter extends BaseEntity {

    public static final String CUST_DETAIL_INSTANCE_ID = "custDetailInstanceId";
     .
     .
     .
     @ManyToOne(fetch = FetchType.LAZY)
     @JoinColumn(name = CUST_DETAIL_INSTANCE_ID)
     private CustomerDetailParameter custDetailInstanceId;
    .
    .
}

и

@Entity
@Table(name = "T_LIFE_CYCLE_CUST_DETAIL_PARM")
@Data
public class CustomerDetailParameter extends BaseEntity {
   .
   .
   .
}

их суперкласс

@MappedSuperclass
@Data
public class BaseEntity {
    @Id
    @Column(name = "INSTANCE_ID")
    private Timestamp instanceId;
   .
   .
   .
}

Для запроса этих таблиц у меня есть спецификация

import static com.garanti.proactiveretention.data.ActionCriteriaParameter.*;

public class ActionCriteriaParameterSpecification  implements Specification<ActionCriteriaParameter> {

    private Long custDetailInstanceId;
    .
    .
    .

    public ActionCriteriaParameterSpecification(Long custDetailInstanceId, ...) {
        this.custDetailInstanceId= custDetailInstanceId;
    .
    .
    .

    }

    @Override
    public Predicate toPredicate(Root<ActionCriteriaParameter> root, CriteriaQuery<?> criteriaQuery, CriteriaBuilder criteriaBuilder) {

        Join<ActionCriteriaParameter, CustomerDetailParameter> join = root.join(CUST_DETAIL_INSTANCE_ID);

        List<Predicate> predicates = new ArrayList<>();
        if (this.custDetailInstanceId!= null) predicates.add(criteriaBuilder.equal(join.get(CUST_DETAIL_INSTANCE_ID), custDetailInstanceId));
    .
    .
    .

        return criteriaBuilder.and(predicates.toArray(new Predicate[0]));
    }


}

Когда я пытаюсь выполнить запрос с CRUDRepository

actionCriteriaParameterRepository.findAll(new ActionCriteriaParameterSpecification(customerDetailParameter, status, actionType, min, max, explanationText)).stream().map(this::convertToActionCriteriaDTO).collect(Collectors.toList());

Я получаю сообщение об ошибке:

java .lang.IllegalArgumentException: Невозможно найти атрибут с заданное имя [custDetailInstanceId] для этого ManagedType [com.garanti.proactiveretention.data.BaseEntity]

1 Ответ

0 голосов
/ 26 марта 2020

Вы должны использовать имена полей сущностей внутри Specification вместо имен столбцов базы данных.

@Entity
@Table(name = "T_LIFE_CYCLE_CUST_DETAIL_PARM")
@Data
public class ActionCriteriaParameter extends BaseEntity {

    public static final String CUST_DETAIL_INSTANCE_ID = "CUST_DETAIL_INSTANCE_ID"; // database column name
     .
     .
     .
     @ManyToOne(fetch = FetchType.LAZY)
     @JoinColumn(name = CUST_DETAIL_INSTANCE_ID) // database column name
     private CustomerDetailParameter customerDetailParameter; // entity field name
    .
    .
}

Код спецификации

    @Override
    public Predicate toPredicate(Root<ActionCriteriaParameter> root, CriteriaQuery<?> criteriaQuery, CriteriaBuilder criteriaBuilder) {

        Join<ActionCriteriaParameter, CustomerDetailParameter> join = root.join("customerDetailParameter");

        List<Predicate> predicates = new ArrayList<>();
        if (this.custDetailInstanceId!= null) 
           predicates.add(criteriaBuilder.equal(join.get("instanceId"), custDetailInstanceId)); 
           // where "instanceId" - CustomerDetailParameter id field name
           // ???? why BaseEntity field instanceId is Timestamp, but custDetailInstanceId has Long type
    .
    .
    .

        return criteriaBuilder.and(predicates.toArray(new Predicate[0]));
    }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...