Ленивая загрузка подграфа весна отдых API
У меня возникла проблема с отложенной загрузкой в моем API для отдыха, которая работает с Spring. Как вы можете видеть, я сгенерировал через get из API api файл json. Поле MyMedl(id модели:5) в моем поле containsModels(id of модель:1) здесь ноль.
{
"id": 1,
"name": "lenet",
"lossWeights": null,
"loss": "categorical_crossentropy",
"sampleWeightMode": null,
"isInput": false,
"isOutput": false,
"optimizer": {
"id": 1,
"optimizerType": {
"id": 5,
"name": "SGD"
}
},
"coordinates": {
"id": 1,
"xpos": 0,
"ypos": 0
},
"containedModels": [
{
"id": 5,
"name": "testModel2",
"lossWeights": null,
"loss": null,
"sampleWeightMode": null,
"isInput": false,
"isOutput": false,
"optimizer": null,
"coordinates": {
"id": 20,
"xpos": 100,
"ypos": 200
},
"containedModels": null,
"succeededByModels": null,
"succeededByLayers": null,
"containedLayers": null,
"modelConfiguration": {
"id": 1,
"name": "Modèle LeNet5",
"creationDate": "2017-05-11T00:00:00+02:00",
"saveURI": "./tests/scripts/sequential/models/model.json",
"project": {
"id": 1,
"name": "LeNet5",
"creationDate": "2017-10-22T00:00:00+02:00",
"updateDate": "2017-10-23T00:00:00+02:00"
}
}
}
],
"succeededByModels": [],
"succeededByLayers": [],
"containedLayers": [
{
"id": 1,
"name": "input",
"isInput": true,
"isOutput": false,
"isIntermediate": false,
"coordinates": {
"id": 2,
"xpos": 78.376953125,
"ypos": 108.01763916015625
},
"succeededByLayers": [
2
],
"succeededByModels": [],
"layerType": {
"id": 43,
"name": "InputLayer"
}
},
{
"id": 2,
"name": "conv2d_1",
"isInput": false,
"isOutput": false,
"isIntermediate": false,
"coordinates": {
"id": 3,
"xpos": 341.5582275390625,
"ypos": 102.59124755859375
},
"succeededByLayers": [
3
],
"succeededByModels": [],
"layerType": {
"id": 63,
"name": "Conv2D"
}
},
{
"id": 3,
"name": "activation_1",
"isInput": false,
"isOutput": false,
"isIntermediate": false,
"coordinates": {
"id": 4,
"xpos": 623.73193359375,
"ypos": 99.8780517578125
},
"succeededByLayers": [
4
],
"succeededByModels": [],
"layerType": {
"id": 15,
"name": "Activation"
}
},
{
"id": 4,
"name": "max_pooling2d_1",
"isInput": false,
"isOutput": false,
"isIntermediate": false,
"coordinates": {
"id": 5,
"xpos": 941.17724609375,
"ypos": 102.59124755859375
},
"succeededByLayers": [
5
],
"succeededByModels": [],
"layerType": {
"id": 70,
"name": "MaxPooling2D"
}
},
{
"id": 5,
"name": "conv2d_2",
"isInput": false,
"isOutput": false,
"isIntermediate": false,
"coordinates": {
"id": 6,
"xpos": 1253.1962890625,
"ypos": 99.8780517578125
},
"succeededByLayers": [
6
],
"succeededByModels": [],
"layerType": {
"id": 63,
"name": "Conv2D"
}
},
{
"id": 6,
"name": "max_pooling2d_2",
"isInput": false,
"isOutput": false,
"isIntermediate": false,
"coordinates": {
"id": 7,
"xpos": 1540.2081298828125,
"ypos": 99.8780517578125
},
"succeededByLayers": [
7
],
"succeededByModels": [],
"layerType": {
"id": 70,
"name": "MaxPooling2D"
}
},
{
"id": 7,
"name": "activation_2",
"isInput": false,
"isOutput": false,
"isIntermediate": false,
"coordinates": {
"id": 8,
"xpos": 1861.44921875,
"ypos": 99.8780517578125
},
"succeededByLayers": [
8
],
"succeededByModels": [],
"layerType": {
"id": 15,
"name": "Activation"
}
},
{
"id": 8,
"name": "flatten_1",
"isInput": false,
"isOutput": false,
"isIntermediate": false,
"coordinates": {
"id": 9,
"xpos": 2151.32373046875,
"ypos": 99.8780517578125
},
"succeededByLayers": [
9
],
"succeededByModels": [],
"layerType": {
"id": 54,
"name": "Flatten"
}
},
{
"id": 9,
"name": "dense_1",
"isInput": false,
"isOutput": false,
"isIntermediate": false,
"coordinates": {
"id": 10,
"xpos": 2505.89208984375,
"ypos": 98.57888793945312
},
"succeededByLayers": [
10
],
"succeededByModels": [],
"layerType": {
"id": 6,
"name": "Dense"
}
},
{
"id": 10,
"name": "dropout_1",
"isInput": false,
"isOutput": false,
"isIntermediate": false,
"coordinates": {
"id": 11,
"xpos": 2828.763671875,
"ypos": 99.8780517578125
},
"succeededByLayers": [
11
],
"succeededByModels": [],
"layerType": {
"id": 44,
"name": "Dropout"
}
},
{
"id": 11,
"name": "dense_2",
"isInput": false,
"isOutput": false,
"isIntermediate": false,
"coordinates": {
"id": 12,
"xpos": 3121.79052734375,
"ypos": 99.8780517578125
},
"succeededByLayers": [
12
],
"succeededByModels": [],
"layerType": {
"id": 6,
"name": "Dense"
}
},
{
"id": 12,
"name": "dropout_2",
"isInput": false,
"isOutput": false,
"isIntermediate": false,
"coordinates": {
"id": 13,
"xpos": 3452.8017578125,
"ypos": 99.8780517578125
},
"succeededByLayers": [
13
],
"succeededByModels": [],
"layerType": {
"id": 44,
"name": "Dropout"
}
},
{
"id": 13,
"name": "dense_3",
"isInput": false,
"isOutput": false,
"isIntermediate": false,
"coordinates": {
"id": 14,
"xpos": 3784.675048828125,
"ypos": 99.8780517578125
},
"succeededByLayers": [],
"succeededByModels": [
5
],
"layerType": {
"id": 6,
"name": "Dense"
}
}
],
"modelConfiguration": {
"id": 1,
"name": "Modèle LeNet5",
"creationDate": "2017-05-11T00:00:00+02:00",
"saveURI": "./tests/scripts/sequential/models/model.json",
"project": {
"id": 1,
"name": "LeNet5",
"creationDate": "2017-10-22T00:00:00+02:00",
"updateDate": "2017-10-23T00:00:00+02:00"
}
}
}
Это (ниже), как работает конфигурация весной моей модели. Как вы можете видеть, в начале я пытался решить проблему с помощью подграфа, и он прекрасно работал с моим подграфом containsLayers, потому что в прошлом у меня была такая же проблема. К сожалению, такое же исправление не работает с содержащимися моделями.
package com.sg.psg2017.domain;
import com.fasterxml.jackson.annotation.*;
// import com.fasterxml.jackson.annotation.JsonIgnore;
import org.hibernate.annotations.Cache;
import org.hibernate.annotations.CacheConcurrencyStrategy;
import javax.persistence.*;
import javax.validation.constraints.*;
import java.io.Serializable;
import java.util.HashSet;
import java.util.Set;
import java.util.Objects;
/**
* A Model.
*/
@Entity
@Table(name = "model")
@Cache(usage = CacheConcurrencyStrategy.NONSTRICT_READ_WRITE)
// @NamedEntityGraph(name = "Model.containedLayers",
// attributeNodes = @NamedAttributeNode(value = "containedLayers", subgraph = "containedLayers"),
// subgraphs = @NamedSubgraph(name = "containedLayers", attributeNodes = {
// @NamedAttributeNode("succeededByLayers"),
// @NamedAttributeNode("succeededByModels")
// }))
@NamedEntityGraph(name = "Model",
attributeNodes = {
@NamedAttributeNode(value = "containedLayers", subgraph = "containedLayers"),
@NamedAttributeNode(value = "containedModels", subgraph = "containedModels"),
},
subgraphs = {
@NamedSubgraph(name = "containedLayers", attributeNodes = {
@NamedAttributeNode("succeededByLayers"),
@NamedAttributeNode("succeededByModels")
}),
@NamedSubgraph(name = "containedModels", attributeNodes = {
@NamedAttributeNode("containedModels"),
@NamedAttributeNode("succeededByLayers"),
@NamedAttributeNode("succeededByModels")
})
}
)
public class Model implements Serializable {
private static final long serialVersionUID = 1L;
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@NotNull
@Column(name = "name", nullable = false)
private String name;
@Column(name = "loss_weights")
private String lossWeights;
@Column(name = "loss")
private String loss;
@Column(name = "sample_weight_mode")
private String sampleWeightMode;
@Column(name = "is_input")
private Boolean isInput;
@Column(name = "is_output")
private Boolean isOutput;
@OneToOne
@JoinColumn(unique = true)
private Optimizer optimizer;
@OneToOne
@JoinColumn(unique = true)
private Coordinates coordinates;
@OneToMany(mappedBy = "model")
@JsonIgnore
@Cache(usage = CacheConcurrencyStrategy.NONSTRICT_READ_WRITE)
private Set<Strategy> strategies = new HashSet<>();
@ManyToMany
@Cache(usage = CacheConcurrencyStrategy.NONSTRICT_READ_WRITE)
@JoinTable(name = "model_contained_model",
joinColumns = @JoinColumn(name="models_id", referencedColumnName="id"),
inverseJoinColumns = @JoinColumn(name="contained_models_id", referencedColumnName="id"))
private Set<Model> containedModels = new HashSet<>();
@ManyToMany
@Cache(usage = CacheConcurrencyStrategy.NONSTRICT_READ_WRITE)
@JoinTable(name = "model_succeeded_by_model",
joinColumns = @JoinColumn(name="models_id", referencedColumnName="id"),
inverseJoinColumns = @JoinColumn(name="succeeded_by_models_id", referencedColumnName="id"))
private Set<Model> succeededByModels = new HashSet<>();
@ManyToMany
@Cache(usage = CacheConcurrencyStrategy.NONSTRICT_READ_WRITE)
@JoinTable(name = "model_succeeded_by_layer",
joinColumns = @JoinColumn(name="models_id", referencedColumnName="id"),
inverseJoinColumns = @JoinColumn(name="succeeded_by_layers_id", referencedColumnName="id"))
private Set<Layer> succeededByLayers = new HashSet<>();
@ManyToMany
@Cache(usage = CacheConcurrencyStrategy.NONSTRICT_READ_WRITE)
@JoinTable(name = "model_contained_layer",
joinColumns = @JoinColumn(name="models_id", referencedColumnName="id"),
inverseJoinColumns = @JoinColumn(name="contained_layers_id", referencedColumnName="id"))
private Set<Layer> containedLayers = new HashSet<>();
@ManyToOne(optional = false)
@NotNull
private ModelConfiguration modelConfiguration;
@ManyToMany(mappedBy = "containedModels")
@JsonIgnore
@Cache(usage = CacheConcurrencyStrategy.NONSTRICT_READ_WRITE)
private Set<Model> containedByModels = new HashSet<>();
@ManyToMany(mappedBy = "succeededByModels")
@JsonIgnore
@Cache(usage = CacheConcurrencyStrategy.NONSTRICT_READ_WRITE)
private Set<Model> precededByModels = new HashSet<>();
@ManyToMany(mappedBy = "succeededByModels")
@JsonIgnore
@Cache(usage = CacheConcurrencyStrategy.NONSTRICT_READ_WRITE)
private Set<Layer> precededByLayers = new HashSet<>();
// jhipster-needle-entity-add-field - Jhipster will add fields here, do not remove
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getName() {
return name;
}
public Model name(String name) {
this.name = name;
return this;
}
public void setName(String name) {
this.name = name;
}
public String getLossWeights() {
return lossWeights;
}
public Model lossWeights(String lossWeights) {
this.lossWeights = lossWeights;
return this;
}
public void setLossWeights(String lossWeights) {
this.lossWeights = lossWeights;
}
public String getLoss() {
return loss;
}
public Model loss(String loss) {
this.loss = loss;
return this;
}
public void setLoss(String loss) {
this.loss = loss;
}
public String getSampleWeightMode() {
return sampleWeightMode;
}
public Model sampleWeightMode(String sampleWeightMode) {
this.sampleWeightMode = sampleWeightMode;
return this;
}
public void setSampleWeightMode(String sampleWeightMode) {
this.sampleWeightMode = sampleWeightMode;
}
public Boolean isIsInput() {
return isInput;
}
public Model isInput(Boolean isInput) {
this.isInput = isInput;
return this;
}
public void setIsInput(Boolean isInput) {
this.isInput = isInput;
}
public Boolean isIsOutput() {
return isOutput;
}
public Model isOutput(Boolean isOutput) {
this.isOutput = isOutput;
return this;
}
public void setIsOutput(Boolean isOutput) {
this.isOutput = isOutput;
}
public Optimizer getOptimizer() {
return optimizer;
}
public Model optimizer(Optimizer optimizer) {
this.optimizer = optimizer;
return this;
}
public void setOptimizer(Optimizer optimizer) {
this.optimizer = optimizer;
}
public Coordinates getCoordinates() {
return coordinates;
}
public Model coordinates(Coordinates coordinates) {
this.coordinates = coordinates;
return this;
}
public void setCoordinates(Coordinates coordinates) {
System.out.println("=============================A");
System.out.println(coordinates);
System.out.println("=============================A");
this.coordinates = coordinates;
}
// public void setCoordinates(int coordinates) {
// System.out.println("=============================B");
// System.out.println(coordinates);
// System.out.println("=============================B");
// // this.coordinates = coordinates;
// }
public Set<Strategy> getStrategies() {
return strategies;
}
public Model strategies(Set<Strategy> strategies) {
this.strategies = strategies;
return this;
}
public Model addStrategy(Strategy strategy) {
this.strategies.add(strategy);
strategy.setModel(this);
return this;
}
public Model removeStrategy(Strategy strategy) {
this.strategies.remove(strategy);
strategy.setModel(null);
return this;
}
public void setStrategies(Set<Strategy> strategies) {
this.strategies = strategies;
}
public Set<Model> getContainedModels() {
System.out.println("ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ");
//System.out.println(containedModels);
System.out.println("ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ");
return containedModels;
}
public Model containedModels(Set<Model> models) {
this.containedModels = models;
return this;
}
public Model addContainedModel(Model model) {
this.containedModels.add(model);
model.getContainedByModels().add(this);
return this;
}
public Model removeContainedModel(Model model) {
this.containedModels.remove(model);
model.getContainedByModels().remove(this);
return this;
}
public void setContainedModels(Set<Model> models) {
System.out.println("ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ");
System.out.println(models);
System.out.println("ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ");
this.containedModels = models;
}
public Set<Model> getSucceededByModels() {
return succeededByModels;
}
public Model succeededByModels(Set<Model> models) {
this.succeededByModels = models;
return this;
}
public Model addSucceededByModel(Model model) {
this.succeededByModels.add(model);
model.getPrecededByModels().add(this);
return this;
}
public Model removeSucceededByModel(Model model) {
this.succeededByModels.remove(model);
model.getPrecededByModels().remove(this);
return this;
}
public void setSucceededByModels(Set<Model> models) {
this.succeededByModels = models;
}
public Set<Layer> getSucceededByLayers() {
return succeededByLayers;
}
public Model succeededByLayers(Set<Layer> layers) {
this.succeededByLayers = layers;
return this;
}
public Model addSucceededByLayer(Layer layer) {
this.succeededByLayers.add(layer);
layer.getPrecededByModels().add(this);
return this;
}
public Model removeSucceededByLayer(Layer layer) {
this.succeededByLayers.remove(layer);
layer.getPrecededByModels().remove(this);
return this;
}
public void setSucceededByLayers(Set<Layer> layers) {
this.succeededByLayers = layers;
}
public Set<Layer> getContainedLayers() {
return containedLayers;
}
public Model containedLayers(Set<Layer> layers) {
this.containedLayers = layers;
return this;
}
public Model addContainedLayer(Layer layer) {
this.containedLayers.add(layer);
layer.getContainedByModels().add(this);
return this;
}
public Model removeContainedLayer(Layer layer) {
this.containedLayers.remove(layer);
layer.getContainedByModels().remove(this);
return this;
}
public void setContainedLayers(Set<Layer> layers) {
this.containedLayers = layers;
}
public ModelConfiguration getModelConfiguration() {
return modelConfiguration;
}
public Model modelConfiguration(ModelConfiguration modelConfiguration) {
this.modelConfiguration = modelConfiguration;
return this;
}
public void setModelConfiguration(ModelConfiguration modelConfiguration) {
this.modelConfiguration = modelConfiguration;
}
public Set<Model> getContainedByModels() {
return containedByModels;
}
public Model containedByModels(Set<Model> models) {
this.containedByModels = models;
return this;
}
public Model addContainedByModel(Model model) {
this.containedByModels.add(model);
model.getContainedModels().add(this);
return this;
}
public Model removeContainedByModel(Model model) {
this.containedByModels.remove(model);
model.getContainedModels().remove(this);
return this;
}
public void setContainedByModels(Set<Model> models) {
this.containedByModels = models;
}
public Set<Model> getPrecededByModels() {
return precededByModels;
}
public Model precededByModels(Set<Model> models) {
this.precededByModels = models;
return this;
}
public Model addPrecededByModel(Model model) {
this.precededByModels.add(model);
model.getSucceededByModels().add(this);
return this;
}
public Model removePrecededByModel(Model model) {
this.precededByModels.remove(model);
model.getSucceededByModels().remove(this);
return this;
}
public void setPrecededByModels(Set<Model> models) {
this.precededByModels = models;
}
public Set<Layer> getPrecededByLayers() {
return precededByLayers;
}
public Model precededByLayers(Set<Layer> layers) {
this.precededByLayers = layers;
return this;
}
public Model addPrecededByLayer(Layer layer) {
this.precededByLayers.add(layer);
layer.getSucceededByModels().add(this);
return this;
}
public Model removePrecededByLayer(Layer layer) {
this.precededByLayers.remove(layer);
layer.getSucceededByModels().remove(this);
return this;
}
public void setPrecededByLayers(Set<Layer> layers) {
this.precededByLayers = layers;
}
// 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;
}
Model model = (Model) o;
if (model.getId() == null || getId() == null) {
return false;
}
return Objects.equals(getId(), model.getId());
}
@Override
public int hashCode() {
return Objects.hashCode(getId());
}
@Override
public String toString() {
return "Model{" +
"id=" + getId() +
", name='" + getName() + "'" +
", lossWeights='" + getLossWeights() + "'" +
", loss='" + getLoss() + "'" +
", sampleWeightMode='" + getSampleWeightMode() + "'" +
", isInput='" + isIsInput() + "'" +
", isOutput='" + isIsOutput() + "'" +
"}";
}
}
И когда я раскомментирую System.out.prinln в методе getContainedModels, поле containsModel больше не равно нулю, что доказывает, что проблема связана с отложенной загрузкой. Ниже приведен мой model.repository, чтобы помочь вам понять, как я применяю конфигурацию подграфа.,
package com.sg.psg2017.repository;
import com.sg.psg2017.domain.Model;
import org.springframework.stereotype.Repository;
import org.springframework.data.jpa.repository.*;
import org.springframework.data.repository.query.Param;
import java.util.List;
/**
* Spring Data JPA repository for the Model entity.
*/
@SuppressWarnings("unused")
@Repository
public interface ModelRepository extends JpaRepository<Model, Long> {
@Query("select distinct model from Model model left join fetch model.containedModels left join fetch model.succeededByModels left join fetch model.succeededByLayers left join fetch model.containedLayers")
@EntityGraph(value = "Model", type = EntityGraph.EntityGraphType.LOAD)
List<Model> findAllWithEagerRelationships();
@Query("select model from Model model left join fetch model.containedModels left join fetch model.succeededByModels left join fetch model.succeededByLayers left join fetch model.containedLayers where model.id =:id")
@EntityGraph(value = "Model", type = EntityGraph.EntityGraphType.LOAD)
Model findOneWithEagerRelationships(@Param("id") Long id);
}
Я надеюсь, что я достаточно ясно, как я могу получить этот пустой массив вместо нулевого поля?