当我试图更新一个现有的实体时,我有一个奇怪的行为。一个Order
实体有一个time
字段,它是使用java.lang.Date
对象设置的(我知道这个类已经被更高级的类所取代,但它已经足够满足我的需要了)。存在防止两个Order
具有相同time
的唯一约束。
如果我运行以下代码:
final Date date = new Date();
customer.getOrders().forEach(order -> {
order.setTime(date);
//two orders cannot have the same time
date.setTime(date.getTime() + 1000);
});
因为Hibernate试图用相同的time
持久化两个不同的订单,所以抛出了一个DataConstraintViolationException
。然而,这不应该发生,因为每次更新Order
的time
时,date
对象也会更新,并将其时间设置为晚一秒-这实际上发生了,我可以使用调试器看到它。
//first order
binding parameter [5] as [TIMESTAMP] - [Sun Jul 12 11:59:27 CEST 2020]
//second order
binding parameter [5] as [TIMESTAMP] - [Sun Jul 12 11:59:27 CEST 2020]
对我来说,这意味着Hibernate仍然使用date
对象的旧值,尽管它以前已经更新过。
如果我稍微修改一下前面的代码,这个问题就会消失:
final Date date = new Date();
customer.getOrders().forEach(order -> {
//a new Date object is created
order.setTime(new Date(date.getTime()));
//two orders cannot have the same time
date.setTime(date.getTime() + 1000);
});
在这里,我每次更新实体时都会创建一个新的Date
对象。此对象的创建时间与已经存在的date
对象的时间相同,如上所述,每次更新实体时都会正确地更新该对象。
这种奇怪行为的原因可能是什么?我是不是遗漏了什么?
发布于 2020-07-12 10:12:07
final Date date = new Date();
customer.getOrders().forEach(order -> {
order.setTime(date);
//two orders cannot have the same time
date.setTime(date.getTime() + 1000);
});
Date是Java中的一个对象。您只需创建一个实例,并将此实例链接到所有订单。修改此实例将影响此循环中处理的所有订单。
第二个版本(order.setTime(new Date(date.getTime();)为循环的每次迭代创建一个新的"Date“实例
发布于 2020-07-12 10:23:01
创建Date对象时,对象中的时间是一个常量!
因此,每次调用date.getTime()时,它实际上都会获取您创建date对象时的日期和时间。
public class DateTimeTest {
public static void main(final String args[]) throws InterruptedException{
System.out.println("Test case begin");
Date date = new Date();
System.out.println(date.getTime());
TimeUnit.SECONDS.sleep(10);
System.out.println(date.getTime());
}
}
以下是我在控制台中拥有的内容
测试用例开始
1594549131082
1594549131082
你可以看到时间在10秒的睡眠后没有改变
https://stackoverflow.com/questions/62859687
复制相似问题