java中的jpa_在JPA中处理Java的LocalDateTime
java中的jpa
幾天前,我在處理JPA中的LocalDateTime屬性時遇到問題。 在這篇博客文章中,我將嘗試創建一個樣本問題來說明該問題以及我使用的解決方案。
考慮以下實體,該實體為特定公司的員工建模–
@Entity @Getter @Setter public class Employee {@Id@GeneratedValueprivate Long id;private String name;private String department;private LocalDateTime joiningDate; }我使用的是Spring Data JPA,因此創建了以下存儲庫–
@Repository public interface EmployeeRepository extends JpaRepository<Employee, Long> {} 我想找到在特定日期加入公司的所有員工。 為此,我從
JpaSpecificationExecutor –
并寫了如下查詢
@SpringBootTest @RunWith(SpringRunner.class) @Transactional public class EmployeeRepositoryIT {@Autowiredprivate EmployeeRepository employeeRepository;@Testpublic void findingEmployees_joiningDateIsZeroHour_found() {DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");LocalDateTime joiningDate = LocalDateTime.parse("2014-04-01 00:00:00", formatter);Employee employee = new Employee();employee.setName("Test Employee");employee.setDepartment("Test Department");employee.setJoiningDate(joiningDate);employeeRepository.save(employee);// Query to find employeesList<Employee> employees = employeeRepository.findAll((root, query, cb) ->cb.and(cb.greaterThanOrEqualTo(root.get(Employee_.joiningDate), joiningDate),cb.lessThan(root.get(Employee_.joiningDate), joiningDate.plusDays(1))));assertThat(employees).hasSize(1);} }以上測試順利通過。 但是,以下測試失敗了(應該通過了)–
@Test public void findingEmployees_joiningDateIsNotZeroHour_found() {DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");LocalDateTime joiningDate = LocalDateTime.parse("2014-04-01 08:00:00", formatter);LocalDateTime zeroHour = LocalDateTime.parse("2014-04-01 00:00:00", formatter);Employee employee = new Employee();employee.setName("Test Employee");employee.setDepartment("Test Department");employee.setJoiningDate(joiningDate);employeeRepository.save(employee);List<Employee> employees = employeeRepository.findAll((root, query, cb) ->cb.and(cb.greaterThanOrEqualTo(root.get(Employee_.joiningDate), zeroHour),cb.lessThan(root.get(Employee_.joiningDate), zeroHour.plusDays(1))));assertThat(employees).hasSize(1); } 與之前的測試唯一不同的是,在先前的測試中,我將零小時作為加入日期,而在這里,我使用了上午8點。 起初,我覺得很奇怪。 只要將員工的入職日期設置為一天的零小時,測試似乎就會通過,但是如果將其設置為任何其他時間,則測試都會失敗。
為了調查問題,我打開了Hibernate日志記錄,以查看實際查詢和發送到數據庫的值,并在日志中注意到了類似的內容–
顯然,JPA 并未將joinDate屬性視為日期或時間,而是視為VARBINARY類型。 這就是與實際日期比較失敗的原因。
我認為這不是一個很好的設計。 它沒有拋出UnsupportedAttributeException之類的東西,而是默默地嘗試將值轉換為其他值,從而導致隨機比較失敗(不是完全隨機)。 除非您有很強的自動化測試套件,否則在應用程序中很難找到這種類型的錯誤,幸運的是,我的情況是這樣。
現在回到問題。 JPA無法正確轉換LocalDateTime的原因非常簡單。 JPA規范的最新版本(即2.1)是在Java 8之前發布的,因此它無法處理新的Date and Time API。
為了解決該問題,我創建了一個自定義轉換器實現,該實現將LocalDateTime轉換為
將java.sql.Timestamp保存到數據庫之前,反之亦然。 那解決了問題–
每當我嘗試保存LocalDateTime屬性時,上述轉換器將自動應用。 我還可以使用來顯式標記要顯式轉換的屬性
javax.persistence.Convert注釋–
完整的代碼可以在Github上找到 。
翻譯自: https://www.javacodegeeks.com/2017/03/dealing-javas-localdatetime-jpa.html
java中的jpa
總結
以上是生活随笔為你收集整理的java中的jpa_在JPA中处理Java的LocalDateTime的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 城建局备案(城建委备案)
- 下一篇: 亿企赢快捷键(亿企赢软件下载)