hibernate / Spring / Jpa @oneToMany级联更新

时间:2017-12-11 13:24:55

标签: spring hibernate jpa cascade

我试图在春天为我的版本模型中的一个到多个字段添加装饰器cascade = CascadeType.ALL,以便在我更新我的版本时更新每个超级参数。就像你可以在下面看到。

 
    @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() + "'" +
                "}";
        }
    }

我的hyperParameter模型如下所示:

@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并尝试使用它。我将字段parametervalue的值从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}'}
]

当我更新我的版本whitout时,如何更新我的hyperParameters会出现此错误。

3 个答案:

答案 0 :(得分:2)

在HyperParameter类中使用@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

答案 1 :(得分:1)

由于该主题中讨论的内容:Spring data rest one to many cascade all,这两个解决方案实际上都有效,因此我遇到了第二个错误。我只需要添加@JsonManagedReference和@JsonBackReference,因为当我试图以级联方式更新我的HyperParameters时,我在版本引用上遇到了编组问题。

答案 2 :(得分:0)

您只有验证错误。您尝试将interpolatedMessage与null值一起使用。好的,但首先删除此字段上的@NotNull注释。