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.