加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 编程开发 > Java > 正文

java – 使用Date参数时的Spring Data JPA日期“之间”查询问题

发布时间:2020-12-15 01:02:47 所属栏目:Java 来源:网络整理
导读:在我的应用程序中,我使用 Spring Data和hibernate作为JPA提供程序来持久化和读取数据. 我有顶级实体类: @Entity@Getter @Setter@Table(name = "operation")@Inheritance(strategy = InheritanceType.JOINED)@EqualsAndHashCode(of = {"operationId"})public
在我的应用程序中,我使用 Spring Data和hibernate作为JPA提供程序来持久化和读取数据.

我有顶级实体类:

@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;
}

对于继承的类,我有相应的存储库:

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);
}

我用以下方法进行集成测试:

@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,false);
            assertEquals(countRowsForEachType,operations.size());
        }
    }
}

但是由于结果为空而我使用MySql数据库时此测试失败(但是当我切换到HSQLDB时通过)

此外,如果我在测试开始时将延迟“Thread.sleep(1000)”延迟一秒,就在第一行之后,则此测试通过.

当我从Hibernate日志执行SQL时,它给了我正确的结果.我的代码出了什么问题?

解决方法

在JPA中,日期需要时间提示.通常,您可以在设置JPA Query参数时设置TemporalType:
query.setParameter("from",from),TemporalType.TIMESTAMP);

使用Spring Data,您需要使用@Temporal注释,因此您的查询将变为:

@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") @Temporal(TemporalType.TIMESTAMP) Date startDay,@Param("to") @Temporal(TemporalType.TIMESTAMP) Date endDay,@Param("trainingMode") boolean trainingMode
);

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读