Сохраняет ли JPA Entity ссылку на Entity Manager?

@Entity
class Employee{
@Id
String name;
int age;
String gender;
}

Я использую указанный выше объект сущности в качестве ключа в Hashmap:

Employee e1 = new Employee("abc",23,"M")

Теперь, если я создам новый объект с тем же идентификатором и сохраняю его:

@Autowired
EmployeeDao employeeDao;

e1.findByName("abc");

Map<Employee, Boolean> map = new HashMap<>();
map.put(e1, true);

Employee e2 = new Employee("abc",45,"F");
employeeDao.save(e2)

for(Employee ex:map.keySet()){
     map.get(ex);   //Returns null
}

Я понимаю, что мой HashKey (e1) также изменен (на e2). Теперь, поскольку Hashmap использует объекты «Entry», где Key будет объектом объекта «Сотрудник» (который был изменен), действительно ли объекты JPA ссылаются на объекты, хранящиеся в диспетчере объектов? Это почему ключ изменился?

Почему ключ (e1) изменился автоматически?


person user7171758    schedule 25.03.2019    source источник
comment
Вы делаете это внутри транзакции?   -  person Ihar Sadounikau    schedule 25.03.2019
comment
Entity Manager сохраняет объект cashed до тех пор, пока вы его не отсоедините. И загрузить объект по id из кеша. Так что, вероятно, вы меняете связанный объект. Попробуйте отсоединить объект после сохранения   -  person Ihar Sadounikau    schedule 25.03.2019
comment
О каком именно ключе вы говорите?   -  person Jens Schauder    schedule 26.03.2019
comment
@JensSchauder Ключ в HashMap obv   -  person user7171758    schedule 26.03.2019
comment
@IharSadounikau, как только я сохраняюсь, ключ HashMap изменяется. Похоже, что объект Entry‹Employee, value› в Hashmap каким-то образом содержит ссылку на сохраненную сущность.   -  person user7171758    schedule 26.03.2019
comment
В этом вопросе нет ничего очевидного. Если вы создадите два экземпляра e1 и e2 и сохраните e2, e1 не изменится. Либо вы делаете что-то другое, либо ваш вывод о том, что e1 изменен, ошибочен. Пожалуйста, покажите нам исходный код, включая: создание обоих экземпляров, добавление экземпляра в HashMap, сохранение другого экземпляра и определение того, что экземпляр, используемый в HashMap, изменился.   -  person Jens Schauder    schedule 26.03.2019
comment
@JensSchauder Добавлен код для справки. Мой вопрос: почему я получаю null? Это связано с тем, что ключ в записи hashmap меняется. А почему ключ поменяли? Надеюсь, это поможет.   -  person user7171758    schedule 26.03.2019


Ответы (1)


Spring Data JPAs save выполняет слияние под капотом. merge ищет объект с тем же классом и идентификатором в кеше 1-го уровня. Если он находит его, он копирует состояние из аргумента в экземпляр в кеше. Затем грязная проверка гарантирует, что он будет сброшен в базу данных. merge и в свою очередь save также возвращают ту сущность, которая была найдена в кеше 1-го уровня.

Поскольку вы загрузили e1 из базы данных в той же транзакции, она находится в кеше 1-го уровня и изменяется.

person Jens Schauder    schedule 26.03.2019
comment
Итак, e1 содержит ссылку, которая указывает на экземпляр объекта в кеше 1-го уровня? - person user7171758; 26.03.2019