Spring Data JPA - 从字符串转换日期和/或时间时转换失败

时间:2018-06-18 19:37:54

标签: java spring spring-data-jpa

我正在使用Spring Boot和Spring JPA。我有一个带有自定义@Query方法的存储库类。

    public interface MarketForceRepository extends CrudRepository<MarketForceComment, Integer> {

    @Query("SELECT c FROM MarketForceComment c WHERE c.property.id = ?1 and c.commentDate >= '?1' AND  c.commentDate <= '?2'")
    List<MarketForceComment> getByPropAndDate(Integer propID, LocalDate start, LocalDate end);

    @Query("SELECT c FROM MarketForceComment c WHERE c.property.id IN ?1 and c.commentDate >= '?2' AND c.commentDate <= '?3'")
    List<MarketForceComment> getByPropsAndDates(List<Integer> propIDs, LocalDate start, LocalDate end);
}

MarketForceComment类遵循(部分):

    @Table(name = "MarketForceComment", schema = "dmb")
@Entity
public class MarketForceComment {
    @ManyToOne
    @JoinColumn(name = "PropertyID")
    private Property property;

    @Column(name = "CommentDate")
    private LocalDate commentDate;

    @Column(name = "Level")
    private int level;

    @Column(name = "Subject")
    private String subject;

    @Column(name = "Details", columnDefinition = "text")
    private String details;

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "ID")
    private Integer id;  

.... }

每当我尝试运行查询方法时:

@Override
    public List<CommentDTO> getCommentsByStore(int storeID, LocalDate date) {
        List<CommentDTO> dtoList = new ArrayList<>();
        marketRepo.getByPropAndDate(storeID, date.plusMonths(1), date)
                .forEach(c -> dtoList.add(mapper.map(c, CommentDTO.class)));
        guestRepo.getByPropAndDate(storeID, date.plusMonths(1).atStartOfDay(), date.atStartOfDay())
                .forEach(c -> dtoList.add(mapper.map(c, CommentDTO.class)));
        return dtoList;
    }

我收到以下错误: com.microsoft.sqlserver.jdbc.SQLServerException: Conversion failed when converting date and/or time from character string.

我有点困惑。它似乎是一个格式问题(DBMS需要一个&yyyy-MM-dd&#39;或类似的格式),但我认为Java的LocalDate将被表达/转换成可以解析的格式按数据库系统。

任何建议都将不胜感激。 感谢。

编辑:

作为参考,基础故障是参数的顺序(?1,?2,?3):

  public interface MarketForceRepository extends CrudRepository<MarketForceComment, Integer> {

    @Query("SELECT c FROM MarketForceComment c WHERE c.property.id = ?1 and c.commentDate >= ?2 AND  c.commentDate <= ?3")
    List<MarketForceComment> getByPropAndDate(Integer propID, LocalDate start, LocalDate end);

    @Query("SELECT c FROM MarketForceComment c WHERE c.property.id IN ?1 and c.commentDate >= ?2 AND c.commentDate <= ?3")
    List<MarketForceComment> getByPropsAndDates(List<Integer> propIDs, LocalDate start, LocalDate end);
}

2 个答案:

答案 0 :(得分:0)

请查看:How to persist JSR-310 types with Spring Data JPA?

根据您使用的框架版本,您必须向项目添加其他配置,以在实体中使用类似LocalDate的JSR-310类型。

答案 1 :(得分:0)

如果您使用的JPA版本低于2.2,则它不直接支持Java8 LocalDate&amp;来自SqlDate的LocalTime转换,因为它是在Java8之前发布的。您必须通过实现JPA AttributeConverter接口来编写自定义日期转换器。然后,您可以为所有实体类autoApply或者您可以选择性地将其注释到LocalDate实体字段。

import java.sql.Date;
import java.time.LocalDate;
import javax.persistence.AttributeConverter;
import javax.persistence.Converter;

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

    @Override
    public Date convertToDatabaseColumn(LocalDate date) {        
        return Date.valueOf(date);
    }

    @Override
    public LocalDate convertToEntityAttribute(Date value) {
        return value.toLocalDate();
    }
}

使用autoApply = true JPA会自动将此转换器与实体字段为LocalDate相关联。

或者,如果选择autoApply = false,则必须通过注释将转换器类与字段相关联。

@Column(name = "CommentDate")
@Convert(converter = LocalDateConverter.class)
private LocalDate commentDate;

参考JPA 2.2 release spec