我正在尝试使用Java Sping Boot 创建一个REST API,目前正在编写JUnit测试用例。
看起来,给定一个包含java.sql.Date
示例的实体,在将其保存到数据库并返回值save()
后,日期值不再相同。
经过仔细检查,我确实在任何地方都使用java.sql.Date
,而不是java.util.Date
。
我正在使用PostgreSQL和Hibernate进行数据库管理。
下面是有问题的代码:
Booking createdBooking = new Booking(
new Date(System.currentTimeMillis()),
..., // rest of the arguments are not important for the discussion
);
ResponseEntity<BookingDto> response = client.postForEntity(
"/createBooking",
BookingDto.toDTO(createdBooking),
BookingDto.class);
assertEquals(HttpStatus.CREATED, response.getStatusCode());
assertNotNull(response.getBody());
assertEquals(createdBooking.getCheckInDate(), response.getBody().getCheckInDate());
字符串
下面是控制器的实现:
@PostMapping(value = { "/createBooking", "/createBooking/" })
@ResponseStatus(HttpStatus.CREATED)
public BookingDto createBooking(@RequestBody BookingDto bookingDto) {
Booking booking = bookingService.createBooking(bookingDto);
return BookingDto.toDTO(booking);
}
型
下面是简化的服务实现:
public Booking createBooking(BookingDto bookingDto) {
Booking booking = new Booking();
booking.setCheckInDate(bookingDto.getCheckInDate());
// rest of the arguments are not important for the discussion
return bookingRepository.save(booking);
}
型
对于Booking
类,默认构造函数为空。
Assert在检查日期是否相等时失败。输出为:
Expected :2023-11-06
Actual :2023-11-04
型2023-11-06
是我运行测试时的实际GMT和本地时间,2023-11-04
我不知道为什么。
我看过几篇关于使用SimpleDateFormat
,this one的文章,但我相信我的情况有点不同,因为我的日期值在运行数据库后实际上“改变”了。
我正在寻找帮助来解释为什么会发生这种行为,以及如何确保日期值一致。提前感谢。
编辑1:
项目已经用Spring initializr与Sping Boot 3.1.4和Java 17初始化,两者都与我的系统兼容。
对数据库的阅读/写由BookingRepository
处理,它扩展了CrudRepository
,因此由Spring注入:
public interface BookingRepository extends CrudRepository<Booking, Integer> {
...
型
除了应用程序属性之外,我没有定义任何显式的转换或同步:
spring.datasource.driver-class-name=org.postgresql.Driver
spring.jpa.hibernate.ddl-auto=create-drop
spring.datasource.url=jdbc:postgresql://localhost:5432/hotel_management
spring.datasource.username={omitted}
spring.datasource.password={omitted}
型
编辑2:
经过进一步的挖掘,我发现问题出在日期转换上,因为客户端的java.sql.Date
示例被解析为最后一个GMT时间值12:00:00 AM,但服务器端接收到相同的值,但在java.sql.Date
示例中将其作为本地时间值,这是5个小时。四舍五入后,日期将偏离一天。反之亦然。
我仍然在尝试如何解决这个问题,同时继续使用java.sql.Date
,因为在我的情况下,切换到其他数据类型并不是一个很好的选择。
1条答案
按热度按时间6l7fqoea1#
强制应用程序使用UTC时间似乎可以工作。
this是怎么做的