С учетом следующего кода
@Transactional
@GetMapping("/load")
public String load() throws InterruptedException {
final Order order87 = ... load via dao which uses the entityManager
log.info("1 load order87 is in persistence context: {}", entityManager.contains(order87));
Thread.sleep(10000);
entityManager.detach(order87);
log.info("2 load order87 is in persistence context: {}", entityManager.contains(order87));
return "loading done";
}
@Transactional
@GetMapping("/save")
public String save() throws InterruptedException {
final Order order87 = ... load via dao which uses the entityManager
log.info("1 save order87 is in persistence context: {}", entityManager.contains(order87));
Thread.sleep(20000);
log.info("2 save order87 is in persistence context: {}", entityManager.contains(order87));
order87.setName("Cup");
orderDao.save(order87);
return "saving done";
}
Когда оба метода выполняются сразу один за другим - поскольку для entityManager существует только один постоянный контекст - я ожидал бы следующее:
1 load order87 is in persistence context: true
1 save order87 is in persistence context: true
2 load order87 is in persistence context: false
2 save order87 is in persistence context: false
но это было
1 load order87 is in persistence context: true
1 save order87 is in persistence context: true
2 load order87 is in persistence context: false
2 save order87 is in persistence context: true
Оба метода выполняются в отдельных транзакциях, но они совместно используют entityManager, а также его контекст постоянства. Оба объекта entityManager и order87 имеют соответствующие хэш-коды в обоих методах, то есть это один и тот же объект и один и тот же менеджер сущностей. Заказ также имеет такой же постоянный идентификатор (базы данных).
А поскольку: «В любой момент времени в контексте постоянства может существовать только один экземпляр Java с одинаковым постоянным идентификатором. Например, если в контексте постоянства существует Сотрудник с постоянным идентификатором (или идентификатором) 158, то нет другой объект Employee с его идентификатором, установленным в 158, может существовать в том же постоянном контексте. " («Pro JPA 2», 2-е издание, 2013 г.) Я ожидаю, что заказ будет также отсоединен в методе сохранения после того, как метод load отсоединил его.
Как это работает?
Обновление
Я использовал System.identityHashCode
для проверки идентичности объектов, и в результате менеджер сущностей остается тем же, но порядок в обоих методах различен. Но они по-прежнему имеют одинаковую идентификацию базы данных, и должен быть только один экземпляр, верно?