Я хотел бы описать проблему, возникшую у меня в JPA / MySQL;это может вдохновить ваше расследование ...
- Глобальная транзакция начинается
- транзакция 1) новая строка в таблице Адрес (автоинкремент)
- транзакция 2) новая строкана таблицу Entreprise с внешним ключом на таблицу адресов;новый введенный Entreprise связан с новым адресом #ID.
- Конец глобальной транзакции
MYSQL взаимоблокировки для этого случая с ResourceLocal / JPATransactionManager.
На самом деле, кажется, что мы не можем открыть несколько вложенных транзакций.Глобальная транзакция, кажется, объединена с транзакциями 1) и 2).Транзакция 2) заканчивается взаимоблокировкой, поскольку данные не могут быть переданы с помощью таблицы. Новый #Id не готов.
Однако с помощью отладчика мы можем увидеть новый идентификатор строки # id между транзакциями 1 и 2.
Это похоже на вашу проблему?Угадаете ли вы автоинкремент - связь с вашим тупиком?Следующие варианты являются возможными решениями ...
Решение1 Изменить уровень изоляции?-> Как? !! У меня нет ответа ... И я не уверен, что это что-то изменит.
Решение2 Замените стратегию создания идентификаторов сущностей JPA (авто или идентификация)) в пользовательскую таблицу последовательностей.
Solution3
Проверьте, не можете ли вы использовать каскадную стратегию для отношений ManyToOne.
EntrepriseEntity{
@Id @GeneratedValue(strategy=GenerationType.IDENTITY)
@Column(name = "id_entreprise")
private int id;
@ManyToOne(fetch=FetchType.LAZY,cascade=CascadeType.ALL)
@JoinColumn(name = "id_address")
private AddressEntity address;
И затем сохраните обе строки в одном слиянии ():
EntrepriseEntity e=new EntrepriseEntity();
e.setAddress(new AddressEntity());
e=entityManager.merge(e);
Возвращенный экземпляр с вернет вам новые вставленные #ids и магию: больше не тупик ...
Решение № 3 умнее, но требует более глубокого анализа и изменения кода ...