【问题标题】:spring data, hibernate, can not save related entity in requared new transactionspring data,hibernate,无法在requared新事务中保存相关实体
【发布时间】:2019-04-05 16:40:40
【问题描述】:

我有 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) 保存的每个 Charge

看起来像这样:

@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);服务器只是挂起没有错误

【问题讨论】:

  • 你的@Transaction(REQUIRES_NEW) 没用。您正在执行一个内部方法调用,它不会通过代理,因此不会被解释。由于刷新,您会收到异常,但所有内容仍位于单个 tx 中。由于 try/catch,这段代码实际上会破坏你的交易。
  • @M. @Transaction(REQUIRES_NEW) 的实际项目方法中的 Deinum 包含在另一个类(服务)中
  • 请让您的问题反映这一点,以防止错误的假设。
  • @M. Deinum 我编辑了我的问题

标签: hibernate transactions spring-data-jpa spring-transactions


【解决方案1】:

您是否尝试在您的实体中添加@ManyToOne(cascade=CascadeType.MERGE)

@ManyToOne(fetch = FetchType.LAZY, cascade=CascadeType.MERGE)
@JoinColumn(name = "ORIGIN_CHARGE_GUID")
private Charge chargeOrigin;

当您更新charge 时,这应该会更新chargeOrigin。此外,您可以随时合并旧费用和更新新费用。

charge.setIsActive(true);
Charge oldCharge = chargeService.findById(charge.getChargeOrigin().getGuid());
oldCharge.setActive(false);
chargeService.saveOneCharge(oldCharge);
chargeService.saveOneCharge(charge);

在最后一种情况下,您的实体中不应有 @ManyToOne(cascade=CascadeType.MERGE) 注释。

【讨论】:

    猜你喜欢
    • 2019-11-08
    • 2014-05-05
    • 2021-08-24
    • 2018-01-11
    • 1970-01-01
    • 1970-01-01
    • 2023-03-04
    • 2015-12-23
    • 2023-01-27
    相关资源
    最近更新 更多