1

I'm trying to add in the decorator cascade = CascadeType.ALL on the field one to many of my version modele in spring in order to update every hyper parameter when i update my version.Like you can see below.

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

My hyperParameter model looks like this :

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

}

I update a json and try a put with it .I change the value of the field parametervalue from 2 to 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"
    }
  }

But when i do i got a 500 internal serveur error and stack trace like the one bellow about a null constraint violation.

<!-- 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}'}
]

How can i update my hyperParameters when i update my version whitout getting this error.

3 Answers3

2

Use the @PreUpdate and @PrePersist callbacks in the HyperParameter class like so:

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

Refer to this for more information : http://docs.jboss.org/hibernate/core/3.3/reference/en/html/tutorial.html#tutorial-associations-usingbidir

mnj11
  • 111
  • 3
  • I think you mistook the direction in the onetoMany relationship i wrote it in the other way. And it doesn't seem to work i got this error now : org.springframework.dao.DataIntegrityViolationException: could not execute statement; SQL [n/a]; constraint [null]; nested exception is org.hibernate.exception.ConstraintViolationException: could not execute statement at org.springframework.orm.jpa.vendor.HibernateJpaDialect.convertHibernateAccessException(HibernateJpaDialect.java:278) – EDUCATED_SHARK_666 Dec 11 '17 at 14:16
1

Both solution actually work i had a second error because of what is discussed in that topic : Spring data rest one to many cascade all . I just had to add @JsonManagedReference and @JsonBackReference because i had marshalling problem on the reference of version when i tried to update my HyperParameters in cascade.

0

You just have validation error. You try to put interpolatedMessage with null value. Ok but first remove @NotNull annotation on this field.

Den B
  • 843
  • 1
  • 10
  • 26