Java - JPA - создание списка дочерних объектов отменяет изменения, уже внесенные в одну из них в транзакции

Почему открытие непредусмотренного Списка объектов (сущностей) отменяет изменения, уже внесенные в любой из указанных объектов в рамках одной и той же транзакции?

Сценарий:

  • A, B и C - все сущности
  • A содержит ссылку на конкретный экземпляр B, который можно получить с помощью a.getB ();
  • C имеет список объектов B, которые можно получить с помощью c.getListOfB()
  • Следующее верно: c.getListOfB(). Содержит (a.getB())
  • Также было проверено следующее: a.getB() == c.getListOfB(). Get(ProperIndex) (та же ссылка на объект)

Если я сделаю следующее в рамках транзакции:

B b = a.getB();    
b.setOk(true); // <-- Changed from false to true

и затем следуйте с:

c.getListOfB().isEmpty() // <-- Any function will do, I just used .isEmpty() to test it

Тогда b НЕМЕДЛЕННО имеет значение OK снова равным false:/

Это происходит в рамках той же транзакции, прежде чем совершать операции с БД.

Может ли кто-то быть настолько любезным, чтобы объяснить мне, почему EntityManager не знает об изменениях, уже внесенных в вышеуказанную сущность в Транзакции, и как я могу убедиться, что она сохраняет их? Это привело меня к долгому поиску ошибок, и я буквально теряюсь в словах о том, как найти полезные результаты в Интернете.

РЕДАКТИРОВАТЬ: Проблема в том, что когда я создаю экземпляр List с помощью метода.isEmpty(), JPA снова "читает" дочерние объекты из БД, возвращая изменение, которое я уже внес в один из его дочерних элементов ранее в транзакции. Я чувствую, что он ДОЛЖЕН знать, что один из дочерних объектов уже находится в постоянном контексте и не смешан с ним.

В настоящее время я работаю над этой проблемой, вызывая c.getListOfB(). IsEmpty (), т. Е. Создавая экземпляр List, ДО внесения изменений в b, но это вряд ли удовлетворительное решение, тем более объяснение проблемы.

2 ответа

Сделайте переменные статичными, чтобы использовался тот же экземпляр.

a.getB() == c.getListOfB().get(ProperIndex) не является правильным.

При сравнении двух объектов используйте метод equals() вместо "=="

== будет сравнивать ссылки на объекты.

equals() сравнивает свойства объекта.

В вашем случае вам нужно сравнить первичный ключ этого объекта, который является одним свойством объекта сущности.

Следующее верно: c.getListOfB(). Содержит (a.getB ())

Следующее также верно: a.getB(). Equals(c.getListOfB(). Get (ProperIndex))

Не уверен, что hibernate вернет тот же экземпляр, на который ссылаются, при вызове a.getB () и c.getListOfB (). Get (ProperIndex), поэтому не используйте == при сравнении двух свойств objecs.

Другие вопросы по тегам