弹簧数据的JPA清除链接实体的所有参数后持续

geoffreydv:

我试图使用JPA(使用Hibernate),以节省2元。春天的数据提供了接口,但我不认为它在这里很重要。

我有一个称为“模式”主要实体。这种模式有很多“参数”实体的联系。我正在写一个方法来保存模型及其参数。

这是方法:

  private void cascadeSave(Model model) {

    modelRepository.save(model);

    for (ParameterValue value : model.getParameterValues()) {
        parameterValueRepository.save(value);
    }
}

这就是问题:

当我打开一个模型,之前已经存在,增加一些新的参数,然后调用此方法来拯救他们两个奇怪的事情发生了:

第一保存(modelRepository.save)之前,这是模型的数据看起来调试时,如:

在这里输入图像描述

该模型具有两个参数,以填充在值(名称和型号被填充)。

现在,保存模型中先保存在我的方法后,这种情况发生。请注意,对象引用是不同的一个,因为Hibernate一定做了什么神奇和重建的值,而不是放任他们:

在这里输入图像描述

出于某种原因,休眠清除集合中的所有参数的属性。

现在,当新的参数保存在下面的代码发生失败,因为没有空约束等。

我的问题:为什么休眠清除所有领域的?

以下是相关的映射:

的parameterValue

@Entity
@Table(name = "tbl_parameter_value")
@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
@DiscriminatorColumn(name = "PARAMETER_TYPE")
public abstract class ParameterValue extends AbstractBaseObject {

    @Column(nullable = false)
    @NotBlank
    private String name;
    private String stringValue;
    private Double doubleValue;
    private Integer intValue;
    private Boolean booleanValue;
    @Enumerated(EnumType.STRING)
    private ModelType modelParameterType;
    @Column(precision = 7, scale = 6)
    private BigDecimal bigDecimalValue;
    @Lob
    private byte[] blobValue;

    ParameterValue() {
    }

    ParameterValue(String name) {
        this.name = name;
    }

模型参数值

@Entity
@DiscriminatorValue(value = "MODEL")
public class ModelParameterValue extends ParameterValue {

    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "model_id", foreignKey = @ForeignKey(name = "FK_VALUE_MODEL"))
    private Model model;

    ModelParameterValue() {
        super();
    }

    ModelParameterValue(String name) {
        super(name);
    }

模型

@Entity
@Table(name = "tbl_model")
public class Model extends AbstractBaseObject implements Auditable {

    @OneToMany(fetch = FetchType.LAZY, mappedBy = "model")
    private Set<ModelParameterValue> parameterValues = new HashSet<>();

编辑

我能够以最少的例子来重现此。如果您要更换一切春天的数据确实是这样的罩(EM是JPA的EntityManager)下发生了什么:

public Model simpleTest() {

    Model model = new Model("My Test Model");
    em.persist(model);

    model.addParameter(new Parameter("Param 1"));
    em.merge(model);

    for (Parameter child : model.getParameters()) {
        em.persist(child);
    }

    return model;
}

When the merge is executed, all of the attributes of the parameters are set to null. They are actually just replaced with completely new parameters.

Emil Hotkowski :

I guess you are using Spring Data Jpa as your modelRepository. This indicates following consequences.

Spring Repository Save

S save(S entity)

Saves a given entity. Use the returned instance for further operations as the save operation might have changed the entity instance completely.

So it is normal behaviour which you had encountered.

Code should be changed to :

model = modelRepository.save(model);

for (ParameterValue value : model.getParameterValues()) {
    parameterValueRepository.save(value);
}

EDIT:

I think that your saving function is broken in sense, that you do it backwards. Either you can use CascadeType on your relation or you have to save children first.

Cascade

Cascade works like that "If you save Parent, save Children, if you update Parent, update Children ..."

因此,我们可以把级联在你们的关系像:

@Entity
@Table(name = "tbl_model")
public class Model extends AbstractBaseObject implements Auditable {

    @OneToMany(fetch = FetchType.LAZY, mappedBy = "model", cascade = CascadeType.ALL)
    private Set<ModelParameterValue> parameterValues = new HashSet<>();

然后只保存这样

  private void cascadeSave(Model model) {

    modelRepository.save(model);
    //ParamValues will be saved/updated automaticlly if your model has changed

}

自下而上保存

第二个选择是只先救PARAMS,然后与他们进行建模。

  private void cascadeSave(Model model) {

    model.setParameterValues(
      model.getParameterValues().stream()
       .map(param ->  parameterValueRepository.save(param))
       .collect(Collectors.toSet())
   );
    modelRepository.save(model);
}

我没有检查第二个代码在我的编译器,但这个想法是先救孩子(ParamValues),放入模型,然后保存模型:)

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章