Проблемы спецификации JPA с диапазоном дат - PullRequest
0 голосов
/ 28 марта 2020

Я пытался использовать спецификацию для одного из моих классов JPA. У меня есть модель с именем «Транзакция» с полем даты «updatedAt». Приложение возвращает пустые строки после добавления ввода даты для фильтрации записей. Ниже приведен мой класс спецификации:

private class TransactionSpecification implements Specification<Transaction> {
        private Date startDate;
        private Date endDate;

        TransactionSpecification(DataTablesInput input) {
            String transactionFilter = input.getColumn("updatedAt").getSearch().getValue();
            LOGGER.info("transactionFilter: {}", transactionFilter);

            if (!StringUtils.hasText(transactionFilter)) {
                startDate = endDate = null;
                return;
            }
            String[] bounds = transactionFilter.split(";");
            LOGGER.info("bounds: {}", Arrays.toString(bounds));
            startDate = getValue(bounds, 0);
            endDate = getValue(bounds, 1);
            if (endDate != null) {
                endDate = DateUtils.getEndOfDay(endDate);
            }
            LOGGER.info("start date: {}", startDate);
            LOGGER.info("end date: {}", endDate);
        }

        private Date getValue(String[] bounds, int index) {
            if (bounds.length > index && StringUtils.hasText(bounds[index])) {
                try {
                    LOGGER.info("We got here: [{}} {}", index, bounds[index]);

                    DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
                    return dateFormat.parse(bounds[index]);
                } catch (Exception e) {
                    return null;
                }
            }
            return null;
        }

        @Override
        public Predicate toPredicate(Root<Transaction> root, CriteriaQuery<?> query, CriteriaBuilder criteriaBuilder) {
            Expression<Date> updatedAt = root.get("updatedAt").as(Date.class);

            LOGGER.info("At predicate, start date: {}, and end date: {}", startDate, endDate);

            if (startDate != null && endDate != null) {
                return criteriaBuilder.between(updatedAt, startDate, endDate);
            } else if (startDate != null) {
                return criteriaBuilder.greaterThanOrEqualTo(updatedAt, startDate);
            } else if (endDate != null) {
                return criteriaBuilder.lessThanOrEqualTo(updatedAt, endDate);
            } else {
                return criteriaBuilder.conjunction();
            }
        }

    }

Представление при первой загрузке возвращает все записи, но я получаю пустой набор записей, когда пытаюсь выполнить фильтрацию по диапазону дат, используя updatedAt. Ниже приведен журнал вывода:

2020-03-28 16:56:11.315  INFO 7464 --- [nio-8090-exec-9] c.a.a.c.TransactionsController           : At predicate, start date: Fri Feb 01 00:00:00 WAT 2019, and end date: Sat Mar 28 23:59:59 WAT 2020
2020-03-28 16:56:11.316 DEBUG 7464 --- [nio-8090-exec-9] o.h.q.c.internal.CriteriaQueryImpl       : Rendered criteria query -> select generatedAlias0 from Transaction as generatedAlias0 left join generatedAlias0.sourceWallet as generatedAlias1 left join fetch generatedAlias0.sourceWallet as generatedAlias2 where ( lower(cast(generatedAlias0.updatedAt as string)) like :param0 escape :param1 ) and ( generatedAlias0.updatedAt between :param2 and :param3 ) order by generatedAlias0.id desc
2020-03-28 16:56:11.317 DEBUG 7464 --- [nio-8090-exec-9] o.h.h.internal.ast.QueryTranslatorImpl   : parse() - HQL: select generatedAlias0 from com.aegletec.aeglepay.domains.Transaction as generatedAlias0 left join generatedAlias0.sourceWallet as generatedAlias1 left join fetch generatedAlias0.sourceWallet as generatedAlias2 where ( lower(cast(generatedAlias0.updatedAt as string)) like :param0 escape :param1 ) and ( generatedAlias0.updatedAt between :param2 and :param3 ) order by generatedAlias0.id desc
2020-03-28 16:56:11.318 DEBUGenter code here 7464 --- [nio-8090-exec-9] o.h.hql.internal.ast.ErrorTracker        : throwQueryException() : no errors

Я считаю, что этот фрагмент кода не должен быть частью сгенерированного запроса SQL.

( lower(cast(generatedAlias0.updatedAt as string)) like :param0 escape :param1 )

Ниже приведен отрывок из модели транзакции:

@Entity
@Table(name = "transactions")
@Getter
@Setter
public class Transaction {

    /**
     * 
     */
    private static final long serialVersionUID = 1L;

    public Transaction(){}

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    @Column(unique = true, nullable = false)
    @NotNull(message = "Reference Cannot be null")
    @Size(min=3)
    private String reference;

    private String reference2;

    private String description;

    private String narration;

    @ManyToOne
    private Wallet sourceWallet;

    @ManyToOne
    private Wallet destinationWallet;

    private BigDecimal amount;

    private BigDecimal fee;

    private BigDecimal netAmount;

    private String productName;

    private String responseCode;

    private String responseDescription;

    @Enumerated(EnumType.STRING)
    private Channel channel;

    @Enumerated(EnumType.STRING)
    private TransactionStatus transactionStatus;


    private String thirdPartyReference;

    @Temporal(TemporalType.TIMESTAMP)
    @JsonFormat
    (shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd HH:mm:ss")
    private Date createdAt = new Date();

    @Temporal(TemporalType.TIMESTAMP)
    @JsonFormat
    (shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd HH:mm:ss")
    private Date updatedAt = new Date();

}

Ниже приведен журнал значения фильтра при его перемещении по различным разделам кода в журнале.

2020-03-28 16:56:11.312  INFO 7464 --- [nio-8090-exec-9] c.a.a.c.TransactionsController           : transactionFilter: 2019-02-01;2020-03-28
2020-03-28 16:56:11.312  INFO 7464 --- [nio-8090-exec-9] c.a.a.c.TransactionsController           : bounds: [2019-02-01, 2020-03-28]
2020-03-28 16:56:11.312  INFO 7464 --- [nio-8090-exec-9] c.a.a.c.TransactionsController           : We got here: [0} 2019-02-01
2020-03-28 16:56:11.312  INFO 7464 --- [nio-8090-exec-9] c.a.a.c.TransactionsController           : We got here: [1} 2020-03-28
2020-03-28 16:56:11.313  INFO 7464 --- [nio-8090-exec-9] c.a.a.c.TransactionsController           : start date: Fri Feb 01 00:00:00 WAT 2019
2020-03-28 16:56:11.313  INFO 7464 --- [nio-8090-exec-9] c.a.a.c.TransactionsController           : end date: Sat Mar 28 23:59:59 WAT 2020
2020-03-28 16:56:11.314 DEBUG 7464 --- [nio-8090-exec-9] o.h.e.t.internal.TransactionImpl         : On TransactionImpl creation, JpaCompliance#isJpaTransactionComplianceEnabled == false
2020-03-28 16:56:11.314 DEBUG 7464 --- [nio-8090-exec-9] o.h.e.t.internal.TransactionImpl         : begin
2020-03-28 16:56:11.314 DEBUG 7464 --- [nio-8090-exec-9] org.hibernate.SQL                        : select count(*) as col_0_0_ from transactions transactio0_
2020-03-28 16:56:11.315 DEBUG 7464 --- [nio-8090-exec-9] org.hibernate.loader.Loader              : Result set row: 0
2020-03-28 16:56:11.315 DEBUG 7464 --- [nio-8090-exec-9] org.hibernate.loader.Loader              : Result row: 
2020-03-28 16:56:11.315  INFO 7464 --- [nio-8090-exec-9] c.a.a.c.TransactionsController           : At predicate, start date: Fri Feb 01 00:00:00 WAT 2019, and end date: Sat Mar 28 23:59:59 WAT 2020

Я немного растерялся о том, как еще справиться с этим. Буду признателен за понимание сообщества.

...