Spring Data JPA - 带有“@Param Date”的自定义@Query 不起作用

Posted

技术标签:

【中文标题】Spring Data JPA - 带有“@Param Date”的自定义@Query 不起作用【英文标题】:Spring Data JPA - custom @Query with "@Param Date" doesn't work 【发布时间】:2017-03-29 12:46:20 【问题描述】:

我创建了自定义查询以按 日期 获取发票数据,但它返回 null。我确定我为数据库中存在的查询设置了完全相同的日期。

我使用自定义查询是因为我想要编写更高级的查询。但是这个简单的查询中存在问题。这是我的示例代码:

@Query("select i from Invoice i where " +
        "i.expirationDate = :expDate")
Invoice findCompanyInvoiceByDate(@Param("expDate") Date expDate);

我试过这段代码,但它也不起作用:

 Invoice findByExpirationDate(Date expirationDate);

我还尝试在 Date 和 @Param 之前添加@Temporal(TemporalType.DATE),但结果为空。

【问题讨论】:

您的日期是否还涉及时间、小时、分钟、秒、毫秒等?您确定这些值完全相同吗? 你能从java端添加数据库中存在的日期格式和日期格式expDate的详细信息吗? mysql 数据库中,我将字段设置为“日期时间”。当我从数据库中检索它时,值是完全相同的。 我正在使用“java.util.Date” 尝试将@Temporal(TemporalType.DATE) 放在实体中的字段上 【参考方案1】:

您应该在日期列中使用@Temporal(TemporalType.TIMESTAMP)。如果还不够(仍然返回 null),请在 @Column 注释中添加 columnDefinition

完整的工作示例is here(注意 so-40613171 分支。对于奇怪的存储库名称和类命名感到抱歉。很多案例研究都使用它)。粗略的例子:

Employee.java

@Entity
public class Employee 

  @Id
  private Integer id;
  private String name;
  private String surname;

  @Temporal(TemporalType.TIMESTAMP)
  @Column(name = "birth_date", columnDefinition = "DATETIME")
  private Date birthDate;

  // Other fields, getter setter, etc.

EmployeeRepository.java

public interface EmployeeRepository 
extends JpaRepository<Employee, Integer> 

  @Query("from Employee e where e.birthDate = :birthDate")
  List<Employee> findEmployeeDataByBirthDate(@Param("birthDate") Date birthDate);

样本数据

final SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
Company companySun = companyRepository.save(new Company(42, "Sun microsystems"));
Company companyGoogle = companyRepository.save(new Company(43, "Google"));

employeeRepository.save(new Employee(101, "James", "Gosling", dateFormat.parse("1970-01-01 17:05:05"), companySun));
employeeRepository.save(new Employee(102, "Paul", "Sheridan", dateFormat.parse("1970-01-01 17:05:05"), companySun));
employeeRepository.save(new Employee(103, "Patrick", "Naughton", dateFormat.parse("1970-01-01 17:05:05"), companySun));

employeeRepository.save(new Employee(201, "Lary", "Page", dateFormat.parse("1970-01-01 17:01:05"), companyGoogle));
employeeRepository.save(new Employee(202, "Sergey", "Brin", dateFormat.parse("1970-01-02 17:02:05"), companyGoogle));

测试代码片段

@Test
public void employeService_findByBirthDate() throws ParseException 
    final SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
    List<Employee> result = this.employeeService.findByBirthDate(dateFormat.parse("1970-01-01 17:05:05"));

    Assert.assertEquals(3, result.size());

如果你运行这个,测试就通过了。

HTH

【讨论】:

这个解决方案对我不起作用。我不知道为什么。当然,这是一个非常有用的例子,应该考虑一下,谢谢。【参考方案2】:

我找到了对这个问题有用的答案here。

如果您使用“日期”类型,我认为问题中的代码应该可以工作,但对于“日期时间”,您应该在查询或类似内容中使用“之间”。我找到了适合我的解决方案,代码如下:

@Query("select i from Invoice i where " +
        "i.expirationDate >= :todayMidnight and i.expirationDate < :tomorowMidnight " +
        "order by expirationDate DESC")
List<Invoice> findCompanyInvoiceByDate(@Param("todayMidnight") Date todayMidnight, @Param("tomorowMidnight") Date tomorowMidnight);

【讨论】:

【参考方案3】:

我只是将日期用作字符串并使用nativeQuery = true。对我来说效果很好。

@Query(value ="select * from table st where st.created_date >= ?1", nativeQuery = true)
    List<YourObject> findAllByCreatedDate(@Param("createdDate") @DateTimeFormat(iso = ISO.DATE) String createdDate);

【讨论】:

以上是关于Spring Data JPA - 带有“@Param Date”的自定义@Query 不起作用的主要内容,如果未能解决你的问题,请参考以下文章

带有额外列的 Spring Data JPA 多对多

带有 spring-security AuditorAware 的 spring-data-jpa 应用程序中的 ***Exception

如何使用带有 Pageable 的 Spring Data JPA 分页来更改数据?

带有 Spring Boot 的 Spring Data JPA 中的多个数据源,[重复]

带有 H2 和 data.sql 的 Spring Boot Data JPA - 未找到表

带有 Spring Data JPA 的 Spring Boot 为 Oracle 数据库上的 findOne(...) 提供了无效字符问题