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

标签 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:从字符串转换日期和/或时间时转换失败。

我有点困惑。这似乎是一个格式问题(DBMS 需要“yyyy-MM-dd”或类似格式),但我认为 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);
}

最佳答案

如果您使用的 JPA 版本低于 2.2,它不直接支持 SqlDate 的 Java8 LocalDate 和 LocalTime 转换,因为它是在 Java8 之前发布的。您必须通过实现 JPA AttributeConverter 接口(interface)来编写自定义日期转换器。然后,您可以将其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,只要实体字段为 LocalDate,JPA 就会自动关联此转换器。

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

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

引用JPA 2.2 release spec

关于java - Spring Data JPA - 从字符串转换日期和/或时间时转换失败,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50916404/

相关文章:

javascript - 按下主 GUI 上的按钮时,编辑 GUI JDialog 不会打开,即使正确执行了步骤也是如此

Java 垃圾收集日志消息

java - JavaFX 构造函数中的 SQLException

java - 如何通过多个字符串值查找全部?

java - 批量插入的最佳 JPA ID 生成策略

java - 如何使用 AudioSystem 预加载不同的剪辑?

spring - 在 applicationContext 上执行 SPeL

java - 处理 XML 时出错 'org.springframework.beans.factory.xml.XmlReaderContext.getEnvironment()Lorg/springframework/core/env/Environment;'

java - Spring 轮廓组

mysql - EclipseLink:连接池和 native 查询