错误:列“XX”中存在空值违反非空约束 SPRING

发布于 2025-01-11 23:49:35 字数 3030 浏览 0 评论 0原文

我有一个父子实体 OneToMany 关系。当我 .save 插入且标识符相同时,我希望它更新。

这是我的服务:

@Override
public MsExplodedDTO saveExplodedFactory(MsExplodedFactoryRequestDTO exploded) {
    
    MsProduct prod = msProductRepo.findByProductCode(exploded.getProductCode())
            .orElseThrow(() -> new ResourceNotFound("Data Produk tidak ditemukan!"));

    
    exploded.setProductCode(prod.getId().toString());
    
    MsExploded exp;
    if (explodedRepo.findByExplodedCodeIgnoreCase(exploded.getExplodedCode()).size() > 0) {
        
        MsExploded oldExploded = explodedRepo.findByExplodedCode(exploded.getExplodedCode())
                .orElseThrow(() -> new ResourceNotFound("Data tidak ditemukan!"));
        
        return updateExplodedFactory(exploded, prod);
    }else {
        exp = mapper.DTO2Entity(exploded);
        exp.setId(0L);
        exp.getExplodedDt().forEach(d -> {
            d.setExplodedhd(exp);
        });
        
        return mapper.entity2DTO(explodedRepo.save(exp));
    }
    
}

@Override
public MsExplodedDTO updateExplodedFactory(MsExplodedFactoryRequestDTO exploded, MsProduct prod) {

    MsExploded oldExploded = explodedRepo.findByExplodedCode(exploded.getExplodedCode())
            .orElseThrow(() -> new ResourceNotFound("Data tidak ditemukan!"));

    if (oldExploded.getIsDeleted()) {
        throw new ResourceNotAcceptable("Kode Exploded " + oldExploded.getExplodedCode() + " telah dihapus");
    }

    oldExploded = mapper.updateDTO2Entity(exploded, oldExploded);
    oldExploded.setProduct(prod);
    

    for (MsExplodedDetail exp : oldExploded.getExplodedDt()) {
        exp.setExplodedhd(oldExploded);
    }

    MsExploded obj = explodedRepo.save(oldExploded);

    return mapper.entity2DTO(obj);
}

当我调试更新时,它说

错误:“ms_exploded_header_id”列中的空值违反了非空约束
详细信息:失败行包含 (20, 333, 2, null, null, null, null, null, null, null, null, null, null)。

虽然我已经按照应有的方式插入了存储库,但保存新存储库没有问题,但在更新父级或子级时却没有问题。

这是我的标头实体:

@Data
@Audited
@EntityListeners(AuditingEntityListener.class)
@Entity
@Table(name = "ms_exploded")
@EqualsAndHashCode(callSuper = false, of = "id")
@ToString(of = { "id" })
public class MsExploded extends AuditField implements Serializable {
XX
XX
XX
@OneToMany(mappedBy = "explodedhd", orphanRemoval = true, cascade = CascadeType.ALL)
    private List<MsExplodedDetail> explodedDt = new ArrayList<>();
}

这是我的子实体:

@Data
@Audited
@EntityListeners(AuditingEntityListener.class)
@Entity
@Table(name = "ms_exploded_detail")
public class MsExplodedDetail implements Serializable {
XX
XX
XX
@JsonIgnoreProperties({ "hibernateLazyInitializer", "handler" })
    @JsonIgnore
    @ManyToOne(targetEntity = MsExploded.class)
    @JoinColumn(name = "ms_exploded_header_id", referencedColumnName = "id")
    private MsExploded explodedhd;
}

我很确定在调试时,ms_exploded_header_id 会随标头 ID 一起插入。但我不知道为什么它取消并返回错误。

I have a parent child entity OneToMany relation. When I .save to insert while the identifier is the same, I want it to update.

Here's my service:

@Override
public MsExplodedDTO saveExplodedFactory(MsExplodedFactoryRequestDTO exploded) {
    
    MsProduct prod = msProductRepo.findByProductCode(exploded.getProductCode())
            .orElseThrow(() -> new ResourceNotFound("Data Produk tidak ditemukan!"));

    
    exploded.setProductCode(prod.getId().toString());
    
    MsExploded exp;
    if (explodedRepo.findByExplodedCodeIgnoreCase(exploded.getExplodedCode()).size() > 0) {
        
        MsExploded oldExploded = explodedRepo.findByExplodedCode(exploded.getExplodedCode())
                .orElseThrow(() -> new ResourceNotFound("Data tidak ditemukan!"));
        
        return updateExplodedFactory(exploded, prod);
    }else {
        exp = mapper.DTO2Entity(exploded);
        exp.setId(0L);
        exp.getExplodedDt().forEach(d -> {
            d.setExplodedhd(exp);
        });
        
        return mapper.entity2DTO(explodedRepo.save(exp));
    }
    
}

@Override
public MsExplodedDTO updateExplodedFactory(MsExplodedFactoryRequestDTO exploded, MsProduct prod) {

    MsExploded oldExploded = explodedRepo.findByExplodedCode(exploded.getExplodedCode())
            .orElseThrow(() -> new ResourceNotFound("Data tidak ditemukan!"));

    if (oldExploded.getIsDeleted()) {
        throw new ResourceNotAcceptable("Kode Exploded " + oldExploded.getExplodedCode() + " telah dihapus");
    }

    oldExploded = mapper.updateDTO2Entity(exploded, oldExploded);
    oldExploded.setProduct(prod);
    

    for (MsExplodedDetail exp : oldExploded.getExplodedDt()) {
        exp.setExplodedhd(oldExploded);
    }

    MsExploded obj = explodedRepo.save(oldExploded);

    return mapper.entity2DTO(obj);
}

When I debug to update, it says

ERROR: null value in column "ms_exploded_header_id" violates not-null constraint
Detail: Failing row contains (20, 333, 2, null, null, null, null, null, null, null, null, null, null).

While I already insert the repo as it should, it's no problem in saving a new but when update the parent or child it.

Here's my header entity:

@Data
@Audited
@EntityListeners(AuditingEntityListener.class)
@Entity
@Table(name = "ms_exploded")
@EqualsAndHashCode(callSuper = false, of = "id")
@ToString(of = { "id" })
public class MsExploded extends AuditField implements Serializable {
XX
XX
XX
@OneToMany(mappedBy = "explodedhd", orphanRemoval = true, cascade = CascadeType.ALL)
    private List<MsExplodedDetail> explodedDt = new ArrayList<>();
}

And here's my child entity:

@Data
@Audited
@EntityListeners(AuditingEntityListener.class)
@Entity
@Table(name = "ms_exploded_detail")
public class MsExplodedDetail implements Serializable {
XX
XX
XX
@JsonIgnoreProperties({ "hibernateLazyInitializer", "handler" })
    @JsonIgnore
    @ManyToOne(targetEntity = MsExploded.class)
    @JoinColumn(name = "ms_exploded_header_id", referencedColumnName = "id")
    private MsExploded explodedhd;
}

I'm pretty sure when I debug, ms_exploded_header_id is inserted with the header id. But I don't know why it cancelled and returned the error.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

划一舟意中人 2025-01-18 23:49:35

确保 MsExploded.explodedDtMsExplodedDetail.explodedhd 始终一致。即,以下断言应该成立:

msExploded.explodedDt.forEach(dt -> assertThat(dt.explodedhd).isEqualTo(msExploded);
assertthat(msExplodedDetail.explodedhd).contains(msExplodedDetail)

我怀疑您(或映射器)在向 MsExploded 添加详细信息时留下 MsExplodedDetail.explodedhd null

Make sure that MsExploded.explodedDt and MsExplodedDetail.explodedhd are always consistent. I.e. the following assertions should hold:

msExploded.explodedDt.forEach(dt -> assertThat(dt.explodedhd).isEqualTo(msExploded);
assertthat(msExplodedDetail.explodedhd).contains(msExplodedDetail)

I suspect you (or the mapper) leave MsExplodedDetail.explodedhd null when adding a detail to an MsExploded.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文