Гибернация с использованием старого значения объекта для привязки - PullRequest
0 голосов
/ 12 июля 2020

У меня странное поведение, когда я пытаюсь обновить существующий объект. Сущность Order имеет поле time, которое задается с помощью объекта java.lang.Date (я знаю, что этот класс был заменен более продвинутыми, но он достаточно хорош для моих нужд). Существует уникальное ограничение, которое не позволяет двум Order s иметь одинаковые 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);
});

Выдается DataConstraintViolationException , потому что Hibernate пытался сохранить два разных заказа с одним и тем же time. Однако этого не должно происходить, потому что каждый раз, когда обновляется Order s time, обновляется и объект date, устанавливая время на одну секунду позже - это на самом деле происходит, я могу увидеть это, используя отладчик. Однако, если я смотрю журнал Hibernate, я вижу следующее:

//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, который, как указано, корректно обновляется каждый раз при обновлении объекта.

Что может быть причиной такого странного поведения? Я что-то упускаю?

Ответы [ 2 ]

1 голос
/ 12 июля 2020
final Date date = new Date();
customer.getOrders().forEach(order -> {
    order.setTime(date);
    //two orders cannot have the same time
    date.setTime(date.getTime() + 1000);
});

Дата - это объект в Java. Вы создаете ровно один экземпляр и связываете этот экземпляр со всеми заказами. изменение этого одного экземпляра повлияет на все заказы, обрабатываемые в этом l oop.

ваша вторая версия (order.setTime (new Date (date.getTime ()));) создает новый экземпляр «Date» для каждая итерация l oop

0 голосов
/ 12 июля 2020

когда вы создаете объект 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 секунд сна

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...