我有一个包含java.time.LocalDateTime类型的atttribute的类。
public class MyClass{
// ...
private LocalDateTime fecha;
// ...
}
我正在使用Spring Data存储库。我想要完成的是根据日期查询实体:
@Service
public interface IRepository extends CrudRepository<MyClass, UUID> {
// ...
public void deleteByFecha(LocalDate fecha);
// ...
}
但这不起作用,因为抛出异常:
org.springframework.dao.InvalidDataAccessApiUsageException:参数值[2016-10-05]与预期类型[java.time.LocalDateTime(n / a)];
不匹配
所以问题是如何通过 fecha 查询数据库中的MyClass,但是使用LocalDate?
修改的 为了防止有人面临同样的问题,我想出了一个解决方案:修改Repository的方法,使其看起来如下:
import org.springframework.transaction.annotation.Transactional;
import org.springframework.data.jpa.repository.Modifying;
import org.springframework.data.jpa.repository.Query;
// ...
@Service
public interface IRepository extends CrudRepository<MyClass, UUID> {
@Transactional
@Modifying
@Query("DELETE FROM MyClass mtc WHERE YEAR(mtc.fecha)=?1 AND MONTH(mtc.fecha)=?2 AND DAY(mtc.fecha)=?3")
public void deleteByFecha(Integer year, Integer month, Integer day);
}
答案 0 :(得分:1)
LocalDateTime
和LocalDate
是不兼容的类型(尽管它们都实现了LocalDateTime#toLocalDate,以防您可以使用它)。
否则,您可以使用{{3}}转换方法。
答案 1 :(得分:1)
试试这个(未经测试):
$
答案 2 :(得分:0)
我知道这是一个老问题,但对于未来,遇到同样问题的人可以使用此解决方案:
default void delByFecha(@RequestParam(name = "date") @DateTimeFormat(iso = ISO.DATE) LocalDate date)
它完美无缺!
答案 3 :(得分:0)
Zombie Thread,但以为我会把解决方案丢进去。
我有一个类似的问题,我最终使用了休眠@Formula
例如:
class MyClass {
private LocalDateTime fecha;
/* fecha referenced within the annotation should be the column name.
* So, if it's different the Java field name (i.e. fecha_dtm or something),
* make sure to use it.
*/
@Formula("CAST(fecha as DATE)")
private LocalDate fechaDate;
}
然后您的存储库:
public interface IRepository extends CrudRepository<MyClass, UUID> {
deleteByFechaDate(LocalDate fecha); // note it's FechaDate, not Fetcha
}
尝试坚持符合ANSI SQL的功能(CAST
与SQL-92兼容,因此已被广泛接受),以确保数据库实现之间的一致性。但是,可以使用特定于数据库的功能,您只会失去可移植性。
希望这对您有所帮助!
答案 4 :(得分:0)
我今天有一个similar question(我正在进行SELECT,而不是DELETE),并将其发布到此处后,我想出了两种解决方案:
@Query(value = "DELETE FROM MyClass mc WHERE DATE(fecha) =:fecha", nativeQuery = true)
public void deleteByFecha(LocalDate fecha);
或者,在Cepr0的answer之后,我成功地测试了他的解决方案:
default void deleteByFecha(LocalDate fecha) {
deleteByFechaBetween(fecha.atStartOfDay(), fecha.plusDays(1).atStartOfDay());
}
void deleteByFechaBetween(LocalDateTime from, LocalDateTime to);