У меня есть Entity, имеющий отношение к этому объекту.
@Data
@Entity
@Table(name = "CHARGES")
public class Charge {
@Id
@Column(name = "GUID", nullable = false)
private String guid;
...
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "ORIGIN_CHARGE_GUID")
private Charge chargeOrigin;
@Column(name = "IS_ACTIVE")
private Boolean isActive;
Столбец IS_ACTIVE имеет ограничение (только один Charge может быть true)
Каждый заряд, который я сохраняю в методах с @Transactional(propagation = Propagation.REQUIRES_NEW)
Это выглядит так:
@Transactional
public void mainMethod { // Root transaction
for (Charge charge: charges) {
//try
saveOneCharge(charges);
//catch
}
}
@Transactional(propagation = Propagation.REQUIRES_NEW)//internal transaction
public Charge saveOneCharge(Charge charge) {
return chargesRepository.saveAndFlush(charge);
}
Но теперь мне нужно поменять isActive в обеих зарядках:
charge.seActive(True);
charge.getChargeOrigin().setActive(false);
chargeService.saveOneCharge(charge)
и я получаю исключение (исключение ограничения)
Мне нужно изменить этот код на:
charge.setIsActive(false);
charge.getChargeOrigin().setActive(false);
Charge deactivatedCharge = chargeService.saveAndFlush(charge.getChargeOrigin());
charge.setChargeOrigin(deactivatedCharge);
chargeService.saveOneCharge(charge)
Но в этом случае мой сервер не выдает исключений, а зависает.
РЕДАКТИРОВАТЬ
Я немного переписал код, ища ответ, и вот часть настоящего проекта:
@Transactional
private void methodWithMainTransaction() {
for (Charge charge: charges) {
chargeService.changeChargeActivation(charges);
}
метод обслуживания:
@Override
@Transactional(propagation = Propagation.REQUIRES_NEW)
public Charge changeChargeActivation(Charge charge) {
Charge chargeOrigin = charge.getChargeOrigin();
if (chargeOrigin != null) {
chargeOrigin.setIsActive(!chargeOrigin.getIsActive());
chargesRepository.saveAndFlush(chargeOrigin);
}
charge.setIsActive(!charge.getIsActive());
return chargesRepository.saveAndFlush(one);
}
На линии chargesRepository.saveAndFlush(chargeOrigin); сервер просто зависает без ошибок
@M. Метод Deinum в реальном проекте с @Transaction(REQUIRES_NEW) содержится в другом классе (сервисе)
Пожалуйста, позвольте вашему вопросу отразить это, чтобы избежать неправильных предположений.
@M. Deinum я отредактировал свой вопрос





Вы пробовали добавить @ManyToOne(cascade=CascadeType.MERGE) в свой объект?
@ManyToOne(fetch = FetchType.LAZY, cascade=CascadeType.MERGE)
@JoinColumn(name = "ORIGIN_CHARGE_GUID")
private Charge chargeOrigin;
Это должно обновить chargeOrigin, когда вы обновите charge. Кроме того, вы всегда можете объединить старую плату и обновить новую.
charge.setIsActive(true);
Charge oldCharge = chargeService.findById(charge.getChargeOrigin().getGuid());
oldCharge.setActive(false);
chargeService.saveOneCharge(oldCharge);
chargeService.saveOneCharge(charge);
В последнем случае у вас не должно быть аннотации @ManyToOne(cascade=CascadeType.MERGE) в вашей сущности.
Ваш
@Transaction(REQUIRES_NEW)бесполезен. Вы выполняете внутренний вызов метода, который не проходит через прокси и, следовательно, не интерпретируется. Вы получаете исключение из-за сброса, но все по-прежнему в одном tx. Этот код действительно нарушает ваш tx из-за try / catch.