JPA Spring存储库日期过滤返回空数组

时间:2016-04-07 08:35:32

标签: java spring hibernate spring-data spring-data-jpa

在两个日期之间调用查询返回一个空数组,但不应返回。

我正在使用这个“简单”的弹簧库:

import java.time.LocalDate;
import java.util.List;
import org.springframework.data.repository.CrudRepository;
import com.company.app.domain.DailySales;

public interface DailySalesRepo extends CrudRepository<DailySales, Long> {

    public List<DailySales> findByDateBetween(LocalDate start, LocalDate end);
}

我在我的服务中调用了这个方法:

public class ImplSalesService implements SaleService {

    private static final long serialVersionUID = 1L;
    protected final Log logger = LogFactory.getLog(getClass());

    @Autowired
    private DailySalesRepo dailySalesRepo;

    public List<DailySales> getDailySales(LocalDate start, LocalDate end) {
        logger.debug("getDailySales with params start/end: " + start.toString() + "/" + end.toString());
        List<DailySales> result = dailySalesRepo.findByDateBetween(start, end);
        return result;
    }   
}

我知道hibernate正在获取权限参数,因为我可以在日志中看到:

Hibernate: select dailysales0_.id as id1_0_, dailysales0_.amount as amount2_0_, dailysales0_.currency as currency3_0_, dailysales0_.date as date4_0_, dailysales0_.tenantId as tenantId5_0_ from agg_dailysells dailysales0_ where dailysales0_.date between ? and ?
10:16:03,674 TRACE BasicBinder:83 - binding parameter [1] as [VARBINARY] - 2016-02-01
10:16:03,682 TRACE BasicBinder:83 - binding parameter [2] as [VARBINARY] - 2016-05-12

将该跟踪复制到SQL控制台会返回101项:

select dailysales0_.id as id1_0_, dailysales0_.amount as amount2_0_, dailysales0_.currency as currency3_0_, dailysales0_.date as date4_0_, dailysales0_.tenantId as tenantId5_0_ from agg_dailysells dailysales0_ where dailysales0_.date between "2016-02-01" and "2016-05-12";

结果:1​​01行返回

List<DailySales> result获得一个空列表。

我做错了什么?

我的实体看起来像:

@Entity
@Table(name="agg_dailysells")
public class DailySales implements Serializable {

    private static final long serialVersionUID = 1L;

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Integer id;
    private Integer tenantId;
    private LocalDate date;
    private Double amount;
    private Integer currency;

    ... getters and setters go here ...

2 个答案:

答案 0 :(得分:2)

据我所知,Hibernate 4不支持Java 8 Time API。您应该使用java.util.Date而不是任何Java 8 Time抽象或升级到Hibernate 5,并将hibernate-java8模块添加到您的依赖项。有关Java LocalDate和Hibernate 4的更多信息,请参阅此question

答案 1 :(得分:1)

Hibernate 4不支持Java 8 LocalDate或LocalDateTime API。原因是Hibernate 4和JPA 2.1在Java 8之前发布。\

幸运的是,Jpa 2.1支持AttributeConverter将实体的属性转换为数据库列表示,反之亦然。您可以使用此界面在日期 LocalDate 之间进行转换。

您必须将实体属性的两个方法1重写为数据库列,将另一个方法重写为数据库列的属性。

@Converter(autoApply = true)
public class LocalDateAttributeConverter implements AttributeConverter<LocalDate, Date> {

    @Override
    public Date convertToDatabaseColumn(LocalDate locDate) {
        return (locDate == null ? null : Date.valueOf(locDate));
    }

    @Override
    public LocalDate convertToEntityAttribute(Date sqlDate) {
        return (sqlDate == null ? null : sqlDate.toLocalDate());
    }
}

在实体列定义中使用此转换器

@Entity
@Table(name="agg_dailysells")
public class DailySales implements Serializable {

    private static final long serialVersionUID = 1L;

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Integer id;
    private Integer tenantId;

    @Column
    @Convert(converter = LocalDateAttributeConverter.class)
    private LocalDate date;

    private Double amount;
    private Integer currency;

请查看此博客post