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