Я пытался использовать спецификацию для одного из моих классов 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
Я немного растерялся о том, как еще справиться с этим. Буду признателен за понимание сообщества.