Различное поведение персистентности с In-Memory и MySQL DB

У меня есть родительский объект и дочерний объект с отношением один ко многим.

При использовании @DataJpaTest (т. Е. При настройке базы данных в памяти) работает следующее:

LOG.info("Creating stops");
Stop stop1 = new Stop(new Time(0), "Acton Town", new HashSet<>());
Set<Stop> stops = new HashSet<>();
stops.add(stop1);

LOG.info("Creating and persisting routes");
Route route = routeRepository.save(new Route("something", "return"));

LOG.info("Adding stops to route");
stops.forEach(route::addStop);

Он правильно вставляет маршрут и каждого потомка, и я могу получить маршрут позже и получить ту же информацию обратно.

Однако, когда я повторяю это в моем сервисе при использовании реального источника данных (локальной базы данных MySQL), персистирование CASCADE.ALL, по-видимому, не происходит, и я в конечном итоге не вставляю остановки, но маршрут сохраняется и назначается. Я БЫ.

Я следовал совету со всего сайта, используя метод "addEntity" в родительском элементе, который настраивал двунаправленные отношения, но он не работает за пределами набора тестов.

Кто-нибудь знает, почему это может быть?

1 ответ

Решение

Поэтому одним из различий между моим тестом и моим сервисом было использование entityManager.flush().

Добавляя @Transactional к моему методу обслуживания, дочерние элементы сохраняются, поскольку это оборачивает вызов метода в прокси-сервере AOP, который по существу делает это:

transaction.begin()
service.method()
transaction.commit()

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

Причина, по которой я раньше этого не замечал в других сервисах, заключается в том, что я использовал CrudRepository для сохранения сущностей, которые бы сразу же заполняли поле id, так что это по существу зафиксировало бы транзакцию.

На это также может повлиять мультитенантная среда, в которой я работаю, где у меня несколько менеджеров транзакций. Если это так, вам, вероятно, придется указать, какой из них с транзакционной аннотацией выглядит так:

@Transactional("nameoftransactionmanager")
Другие вопросы по тегам