Trong ứng dụng của tôi, tôi đang sử dụng Spring Data và hibernate như nhà cung cấp JPA để duy trì và đọc dữ liệu.Ngày dữ liệu mùa xuân JPA "giữa" vấn đề truy vấn khi sử dụng các tham số ngày
Tôi có đầu lớp mức Entity:
@Entity
@Getter @Setter
@Table(name = "operation")
@Inheritance(strategy = InheritanceType.JOINED)
@EqualsAndHashCode(of = {"operationId"})
public abstract class Operation implements Serializable {
public static final int OPERATION_ID_LENGTH = 20;
@Id
@Column(name = "operation_id", length = OPERATION_ID_LENGTH, nullable = false, columnDefinition = "char")
private String operationId;
@Column(name = "operation_type_code")
@Getter(AccessLevel.NONE)
@Setter(AccessLevel.NONE)
private String operationTypeCode;
@Temporal(TemporalType.TIMESTAMP)
@Column(name = "begin_timestamp", nullable = false)
private Date beginTimestamp = new Date();
@Temporal(TemporalType.TIMESTAMP)
@Column(name = "end_timestamp")
private Date endTimestamp;
@Column(name = "operation_number", length = 6, columnDefinition = "char")
private String operationNumber;
@Enumerated(EnumType.STRING)
@Column(name = "operation_status", length = 32, nullable = false)
private OperationStatus status;
@ManyToOne(optional = false)
@JoinColumn(name = "user_id")
private User user;
@ManyToOne
@JoinColumn(name = "terminal_id")
private Terminal terminal;
@Column(name = "training_mode", nullable = false)
private boolean trainingMode;
}
Đối với lớp được thừa kế tôi có kho tương ứng:
public interface ConcreteOperationRepository extends JpaRepository<ConcreteOperation, String> {
@Query("SELECT o FROM ConcreteOperation o WHERE o.beginTimestamp BETWEEN :from AND :to AND o.status = :status AND o.terminal.deviceId = :deviceId AND o.trainingMode = :trainingMode")
Collection<ConcreteOperation> findOperations(@Param("from") Date startDay,
@Param("to") Date endDay,
@Param("status") OperationStatus status,
@Param("deviceId") String deviceId,
@Param("trainingMode") boolean trainingMode);
}
Và tôi có thử nghiệm tích hợp với các phương pháp sau đây:
@Transactional
@Test
public void shouldFindOperationByPeriodAndStatusAndWorkstationId() {
Date from = new Date(Calendar.getInstance().getTime().getTime());
List<String> terminalIds = loadTerminalIds();
List<OperationStatus> typeForUse = Arrays.asList(OperationStatus.COMPLETED,
OperationStatus.LOCKED, OperationStatus.OPEN);
int countRowsForEachType = 3;
int id = 100001;
for (String terminalId : terminalIds) {
for (OperationStatus status : typeForUse) {
for (int i = 0; i < countRowsForEachType; i++) {
concreteOperationRepository.save(createConcreteOperation(status, terminalId,
String.valueOf(++id)));
}
}
}
Date to = new Date(Calendar.getInstance().getTime().getTime());
for (String terminalId : terminalIds) {
for (OperationStatus status : typeForUse) {
Collection<ConcreteOperation> operations =
concreteOperationRepository.findOperations(from, to, status, terminalId, false);
assertEquals(countRowsForEachType, operations.size());
}
}
}
Nhưng kiểm tra này không thành công khi tôi sử dụng cơ sở dữ liệu MySql do kết quả trống (nhưng chuyển khi tôi chuyển đổi đến HSQLDB)
Ngoài ra, kiểm tra này sẽ trôi qua nếu tôi trì hoãn "Thread.sleep (1000)" trong một giây ở đầu bài kiểm tra, ngay sau dòng đầu tiên.
Khi tôi thực thi SQL từ nhật ký Hibernate, nó cho tôi kết quả đúng. Có gì sai với mã của tôi?
Tôi đã thay đổi Ngày thành LocalDateTime nhưng không giải quyết được sự cố –
Thử 'ZonedDateTime' –