【问题标题】:Spring Data JPA - custom @Query with "@Param Date" doesn't workSpring Data JPA - 带有“@Param Date”的自定义@Query 不起作用
【发布时间】: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) 放在实体中的字段上

标签: spring spring-boot spring-data spring-data-jpa jpql


【解决方案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);
    

    【讨论】:

      猜你喜欢
      • 2018-08-31
      • 2017-09-21
      • 2018-03-20
      • 2012-06-02
      • 1970-01-01
      • 2020-05-20
      • 1970-01-01
      • 2016-02-15
      • 2019-05-29
      相关资源
      最近更新 更多