代码之家  ›  专栏  ›  技术社区  ›  ip696

spring数据,hibernate,无法在请求的新事务中保存相关实体

  •  0
  • ip696  · 技术社区  · 6 年前

    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);

    1 回复  |  直到 6 年前
        1
  •  0
  •   Alain Cruz    6 年前

    @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);
    

    在最后一种情况下,你不应该 实体中的批注。