Метод Delete не влияет на базу данных, если он @Transactional - PullRequest
0 голосов
/ 30 июня 2019

У меня есть этот простой метод для удаления записей из базы данных. Он работал нормально, пока я не добавил аннотацию @Transactional. В этом случае обработка завершается как обычно, но не удаляет объект.

Если я удаляю аннотацию @Transactional или ModelMapper, она работает как задумано. (http://modelmapper.org/). И я не вижу никаких исключений, которые бы объяснили мне откат

Пожалуйста, прости меня за игнорирование некоторых лучших практик в моем коде. Я просто

Это не работает и не повлияет на БД.

@Transactional
public JsonTrain delete(Long id) {
   Wagon wagon = wagonRepository.getOne(id);
   isSafeForDelete(wagon);
   wagonRepository.delete(wagon);
   return modelMapper.map(wagon.getTrain(), JsonTrain.class);
}

Это работает:

public JsonTrain delete(Long id) {
   Wagon wagon = wagonRepository.getOne(id);
   isSafeForDelete(wagon);
   wagonRepository.delete(wagon);
   return modelMapper.map(wagon.getTrain(), JsonTrain.class);
}

И это работает

@Transactional
public void delete(Long id) {
   Wagon wagon = wagonRepository.getOne(id);
   isSafeForDelete(wagon);
   wagonRepository.delete(wagon);
}

Я в порядке с обходным решением, но хотел бы понять причину.

Спасибо

1 Ответ

0 голосов
/ 01 июля 2019

Код, который вы пометили как «рабочий», приводит к гипотезе о том, что отношение «Вагон - Поезд» составляет fetch="EAGER"

Этот код "не работает" и "одна транзакция":

@Transactional
public JsonTrain delete(Long id) {
   Wagon wagon = wagonRepository.getOne(id);
   isSafeForDelete(wagon);
   wagonRepository.delete(wagon);
   return modelMapper.map(wagon.getTrain(), JsonTrain.class);
}

сначала загружает вагон из хранилища (Wagon wagon = wagonRepository.getOne(id)), затем пометьте его как удаленный (wagonRepository.delete(wagon)), см .: Жизненный цикл объекта JPA . Наконец, ссылка Поезд (wagon.getTrain()) передается моделирующему. Из-за гипотезы, высказанной в начале моего ответа, поезд был загружен из базы данных перед удалением Вагона. Чтобы удалить вагон, попробуйте также удалить его из списка вагонов поездов.

Код, который вы пометили как «рабочий», имеет семантику, в которой каждая операция с репозиторием выполняется в отдельной транзакции (Wagon wagon = wagonRepository.getOne(id) и wagonRepository.delete(wagon)). Поэтому, когда вы передаете поезд на модель-картограф, вагон уже удален из базы данных - но - поскольку вагон с поездом был загружен перед удалением, удаленный вагон также должен быть сопоставлен с JsonTrain (при условии, что JsonTran имеет список JsonWagon :)).

...