【问题标题】:How change field that is Entity in Spring Data JPA?如何更改 Spring Data JPA 中的实体字段?
【发布时间】:2020-05-11 10:54:49
【问题描述】:

我有两个实体——TypeReport 和 GroupParameter。 GroupParameter 有一个字段 TypeReport。

我的实体:

组参数

@Entity
@Data
public class GroupParameter {

    @Id
    @GeneratedValue(generator = ID_GENERATOR)
    private Long id;
    private String title;
    private boolean common;
    @ManyToOne
    @JoinColumn(name = "TYPE_REPORT_ID", nullable = false)
    private TypeReport typeReport;

}

类型报告

@Data
@Entity
public class TypeReport {

    @Id
    @GeneratedValue(generator = ID_GENERATOR)
    private Long id;

    @Column(nullable = false)
    private String title;

    @Enumerated(EnumType.STRING)
    @Column(nullable = false)
    private Standard standard;

}

客户端发给我GroupParameterDTO:

@Data
public class GroupParameterDTO {

    private Long id;
    private String title;
    private boolean common;
    private String typeReportId;

}

客户端可以更改 GroupParameter 中的某些字段,并且他可以发送任何字段集: - 标题 - 标题,typeReportId - typeReportId

例如:

{
 title: "new Title"
}

那么我有:

GroupParameterDTO {

    private Long id = null;
    private String title = "new Title";
    private boolean common = false; //It will be ignored
    private String typeReportId = null;

}

当我尝试更改 typeReport 时,我可能有两种情况:

  • typeReportId = null - 我不应该更改 GroupParameter 中的 typeReport
  • typeReportId = something - 我应该更改 GroupParameter 中的 typeReport 而不更改 typeReport 的字段

我该怎么办?

  1. 我通过 id 在 DB 中找到 GroupParameter:

GroupParameter groupParametersFromDB = findById(id);

  1. 我使用从客户端获取的数据填充 GroupParameter:

groupParameterMapper.fillGroupParameters(groupParameters, groupParametersFromDB);

 @Override
    public void fillGroupParameters(GroupParameter source, GroupParameter target) {
        if ( source == null ) {
            return;
        }

        if ( source.getTypeReport() != null ) {
            if ( target.getTypeReport() == null ) {
                target.setTypeReport( new TypeReport() );
            }
            typeReportToTypeReport( source.getTypeReport(), target.getTypeReport() );
        }
        if ( source.getTitle() != null ) {
            target.setTitle( source.getTitle() );
        }
    }

protected void typeReportToTypeReport(TypeReport typeReport, TypeReport mappingTarget) {
        if ( typeReport == null ) {
            return;
        }

        if ( typeReport.getId() != null ) {
            mappingTarget.setId( typeReport.getId() );
        }
        mappingTarget.setTitle( typeReport.getTitle() );
        mappingTarget.setStandard( typeReport.getStandard() );
    }
  1. 我尝试保存我的 GroupParameter: groupParameterRepository.save(groupParametersFromDB);

但我得到了错误。

当我尝试更改 id 时:

org.hibernate.HibernateException:ru.watchlist.domain.TypeReport 实例的标识符从 1 更改为 3

当我不尝试更改id时(仅更改标题时):

org.postgresql.util.PSQLException:错误:“标准”列中的空值违反非空约束

我认为 Repository 会尝试保存 typeReport,而不是在保存 GroupParameter 时将链接更改为 GroupParameter 中的另一个链接。

我不想在保存 GroupParameter 时对 typeReport 进行任何更改。我只想更改 GroupParameter 中 typeReport 的链接。

我该怎么做?

【问题讨论】:

    标签: spring hibernate spring-data-jpa repository


    【解决方案1】:

    如果客户告诉您他/她希望组参数的类型报告 ID 为 3,这并不意味着他/她要更改类型报告的 ID。

    这意味着他/她希望组参数有另一个类型的报告,由ID 3标识。

    因此,您从数据库中获取该类型报告,并将其分配给 group 参数:

    groupParameter.setTypeReport(typeReportRepository.findById(3).orElseThrow(...))
    

    【讨论】:

    • 每次要更改GroupParameter中的typeReport时,是否应该向数据库发出请求?
    • 视情况而定。你想确保类型报告 3 存在,并向客户端抛出一个有意义的错误吗?如果是这样,是的,你需要去数据库。如果没有,那么您可以假设它存在,并在您的存储库上调用 getOne() 而不是 findById()。那不会进入数据库。但是由于违反了 FK 约束,它会在刷新时抛出(希望)异常。
    猜你喜欢
    • 2019-09-21
    • 1970-01-01
    • 2012-08-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-02-06
    • 2019-12-31
    • 2015-09-11
    相关资源
    最近更新 更多