hibernate/Spring/Jpa @oneToMany 级联更新

hibernate/Spring/Jpa @oneToMany cascade update

我正在尝试在装饰器级联 = CascadeType.ALL 中添加我在 spring 中的许多版本模型,以便在我更新我的 version.Like 时更新每个超参数你可以见下文。

    @Entity
    @Table(name = "version")
    @Cache(usage = CacheConcurrencyStrategy.NONSTRICT_READ_WRITE)
    public class Version implements Serializable {

       private static final long serialVersionUID = 1L;

       @Id
        @GeneratedValue(strategy = GenerationType.IDENTITY)
        private Long id;

       @NotNull
        @Column(name = "num", nullable = false)
        private Integer num;

       @Column(name = "creation_date")
        private ZonedDateTime creationDate;

       @Column(name = "execution_date")
        private ZonedDateTime executionDate;

       @Column(name = "weights_uri")
        private String weightsURI;

       @OneToMany(mappedBy = "version", fetch = FetchType.EAGER, orphanRemoval = true)
        @JsonIgnoreProperties({"version", "metricsType"})
        @Cache(usage = CacheConcurrencyStrategy.NONSTRICT_READ_WRITE)
        private Set<ResultExecution> resultExecutions = new HashSet<>();

       @OneToMany(mappedBy = "version", fetch = FetchType.EAGER, orphanRemoval = true, cascade = CascadeType.ALL)
        @JsonIgnoreProperties({"version"})
        @Cache(usage = CacheConcurrencyStrategy.NONSTRICT_READ_WRITE)
        private Set<HyperParameter> hyperParameters = new HashSet<>();
  public Long getId() {
        return id;
    }

        public void setId(Long id) {
            this.id = id;
        }

        public Integer getNum() {
            return num;
        }

        public Version num(Integer num) {
            this.num = num;
            return this;
        }

        public void setNum(Integer num) {
            this.num = num;
        }

        public ZonedDateTime getCreationDate() {
            return creationDate;
        }

        public Version creationDate(ZonedDateTime creationDate) {
            this.creationDate = creationDate;
            return this;
        }

        public void setCreationDate(ZonedDateTime creationDate) {
            this.creationDate = creationDate;
        }

        public ZonedDateTime getExecutionDate() {
            return executionDate;
        }

        public Version executionDate(ZonedDateTime executionDate) {
            this.executionDate = executionDate;
            return this;
        }

        public void setExecutionDate(ZonedDateTime executionDate) {
            this.executionDate = executionDate;
        }

        public String getWeightsURI() {
            return weightsURI;
        }

        public Version weightsURI(String weightsURI) {
            this.weightsURI = weightsURI;
            return this;
        }

        public void setWeightsURI(String weightsURI) {
            this.weightsURI = weightsURI;
        }

        public Set<ResultExecution> getResultExecutions() {
            return resultExecutions;
        }

        public Version resultExecutions(Set<ResultExecution> resultExecutions) {
            this.resultExecutions = resultExecutions;
            return this;
        }

        public Version addResultExecution(ResultExecution resultExecution) {
            this.resultExecutions.add(resultExecution);
            resultExecution.setVersion(this);
            return this;
        }

        public Version removeResultExecution(ResultExecution resultExecution) {
            this.resultExecutions.remove(resultExecution);
            resultExecution.setVersion(null);
            return this;
        }

        public void setResultExecutions(Set<ResultExecution> resultExecutions) {
            this.resultExecutions = resultExecutions;
        }

        public Set<HyperParameter> getHyperParameters() {
            return hyperParameters;
        }

        public Version hyperParameters(Set<HyperParameter> hyperParameters) {
            this.hyperParameters = hyperParameters;
            return this;
        }

        public Version addHyperParameter(HyperParameter hyperParameter) {
            this.hyperParameters.add(hyperParameter);
            hyperParameter.setVersion(this);
            return this;
        }

        public Version removeHyperParameter(HyperParameter hyperParameter) {
            this.hyperParameters.remove(hyperParameter);
            hyperParameter.setVersion(null);
            return this;
        }

        public void setHyperParameters(Set<HyperParameter> hyperParameters) {
            this.hyperParameters = hyperParameters;
        }

        public Set<Data> getData() {
            return data;
        }

        public Version data(Set<Data> data) {
            this.data = data;
            return this;
        }

        public Version addData(Data data) {
            this.data.add(data);
            data.getVersions().add(this);
            return this;
        }

        public Version removeData(Data data) {
            this.data.remove(data);
            data.getVersions().remove(this);
            return this;
        }

        public void setData(Set<Data> data) {
            this.data = data;
        }

        public ModelConfiguration getModelConfiguration() {
            return modelConfiguration;
        }

        public Version modelConfiguration(ModelConfiguration modelConfiguration) {
            this.modelConfiguration = modelConfiguration;
            return this;
        }

        public void setModelConfiguration(ModelConfiguration modelConfiguration) {
            this.modelConfiguration = modelConfiguration;
        }
        // jhipster-needle-entity-add-getters-setters - Jhipster will add getters and setters here, do not remove

        @Override
        public boolean equals(Object o) {
            if (this == o) {
                return true;
            }
            if (o == null || getClass() != o.getClass()) {
                return false;
            }
            Version version = (Version) o;
            if (version.getId() == null || getId() == null) {
                return false;
            }
            return Objects.equals(getId(), version.getId());
        }

        @Override
        public int hashCode() {
            return Objects.hashCode(getId());
        }

        @Override
        public String toString() {
            return "Version{" +
                "id=" + getId() +
                ", num='" + getNum() + "'" +
                ", creationDate='" + getCreationDate() + "'" +
                ", executionDate='" + getExecutionDate() + "'" +
                ", weightsURI='" + getWeightsURI() + "'" +
                "}";
        }
    }

我的超参数模型如下所示:

@Entity
@Table(name = "hyper_parameter")
@Cache(usage = CacheConcurrencyStrategy.NONSTRICT_READ_WRITE)
public class HyperParameter implements Serializable {

   private static final long serialVersionUID = 1L;

   @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

   @NotNull
    @Column(name = "parameter_value", nullable = false)
    private String parameterValue;

   @ManyToOne(optional = false)
    @NotNull
    @JsonIgnoreProperties({"resultExecutions", "hyperParameters", "data", "modelConfiguration"})
    private Version version;
public Long getId() {
    return id;
}

public void setId(Long id) {
    this.id = id;
}

public String getParameterValue() {
    return parameterValue;
}

public HyperParameter parameterValue(String parameterValue) {
    this.parameterValue = parameterValue;
    return this;
}

public void setParameterValue(String parameterValue) {
    this.parameterValue = parameterValue;
}

public Version getVersion() {
    return version;
}

public HyperParameter version(Version version) {
    this.version = version;
    return this;
}

public void setVersion(Version version) {
    this.version = version;
}

public HyperParameterType getHyperParameterType() {
    return hyperParameterType;
}

public HyperParameter hyperParameterType(HyperParameterType hyperParameterType) {
    this.hyperParameterType = hyperParameterType;
    return this;
}

public void setHyperParameterType(HyperParameterType hyperParameterType) {
    this.hyperParameterType = hyperParameterType;
}
// jhipster-needle-entity-add-getters-setters - Jhipster will add getters and setters here, do not remove

@Override
public boolean equals(Object o) {
    if (this == o) {
        return true;
    }
    if (o == null || getClass() != o.getClass()) {
        return false;
    }
    HyperParameter hyperParameter = (HyperParameter) o;
    if (hyperParameter.getId() == null || getId() == null) {
        return false;
    }
    return Objects.equals(getId(), hyperParameter.getId());
}

@Override
public int hashCode() {
    return Objects.hashCode(getId());
}

@Override
public String toString() {
    return "HyperParameter{" +
        "id=" + getId() +
        ", parameterValue='" + getParameterValue() + "'" +
        "}";
}

}

我更新了一个 json 并尝试用它放置。我将字段参数值的值从 2 更改为 3。

{
    "id": 1,
    "num": 1,
    "creationDate": "2017-05-11T00:00:00+02:00",
    "executionDate": null,
    "weightsURI": "tests/scripts/sequential/weights/weights_le_net_5.h5py",
    "resultExecutions": [
      {
        "id": 1,
        "metricValues": "",
        "executionType": "TRAIN",
        "numPrediction": null
      },
      {
        "id": 2,
        "metricValues": "",
        "executionType": "TRAIN",
        "numPrediction": null
      }
    ],
    "hyperParameters": [
      {
        "id": 1,
        "parameterValue": "2",
        "hyperParameterType": {
          "id": 1,
          "name": "epochs",
          "parameterType": "INTEGER",
          "parameterDefaultValue": "0",
          "isRequired": true
        }
      },
      {
        "id": 2,
        "parameterValue": "32",
        "hyperParameterType": {
          "id": 2,
          "name": "batch_size",
          "parameterType": "INTEGER",
          "parameterDefaultValue": "32",
          "isRequired": true
        }
      }
    ],
    "modelConfiguration": {
      "id": 1,
      "name": "Modele LeNet5",
      "creationDate": "2017-05-11T00:00:00+02:00",
      "updateDate": "2017-05-11T00:00:00+02:00",
      "saveURI": "tests/scripts/sequential/models/le_net_5.json"
    }
  }

但是当我这样做时,我得到了一个 500 内部服务器错误和堆栈跟踪,就像下面关于违反空约束的那个。

<!-- What do you expect the result to be? -->

<!-- What is the actual result you get? (Please include any errors.) -->
org.springframework.transaction.TransactionSystemException: Could not commit JPA transaction; nested exception is javax.persistence.RollbackException: Error while committing the transaction
        at org.springframework.orm.jpa.JpaTransactionManager.doCommit(JpaTransactionManager.java:526)


[1:59] 
t org.hibernate.internal.ExceptionConverterImpl.convertCommitException(ExceptionConverterImpl.java:75)
        at org.hibernate.engine.transaction.internal.TransactionImpl.commit(TransactionImpl.java:71)
        at org.springframework.orm.jpa.JpaTransactionManager.doCommit(JpaTransactionManager.java:517)
        ... 153 common frames omitted
Caused by: javax.validation.ConstraintViolationException: Validation failed for classes [com.saagie.picsaagie2017_frontend.domain.HyperParameter] during update time for groups [javax.validation.groups.Default, ]
List of constraint violations:[
        ConstraintViolationImpl{interpolatedMessage='can not be null ', propertyPath=version, rootBeanClass=class com.saagie.picsaagie2017_frontend.domain.HyperParameter, messageTemplate='{javax.validation.constraints.NotNull.message}'}
]

如何在更新我的版本时更新我的​​超参数而不会出现此错误。

像这样在超参数 class 中使用 @PreUpdate 和 @PrePersist 回调:

@PreUpdate
@PrePersist
public void setChildObjects() {
    if (getVersions() != null)
    {
        for (Version version : getVersions())
        {
            version.setHyperParameters (this);
        }
    }
}

更多信息请参考:http://docs.jboss.org/hibernate/core/3.3/reference/en/html/tutorial.html#tutorial-associations-usingbidir

您只是遇到了验证错误。您尝试将 interpolatedMessage 设置为空值。好的,但首先删除此字段上的 @NotNull 注释。

这两种解决方案都有效我有第二个错误,因为该主题中讨论的内容:。我只需要添加@JsonManagedReference 和@JsonBackReference,因为当我尝试在级联中更新我的超参数时,我在版本参考上遇到了编组问题。