First of all I know that there are several threads with solutions but I don't understand them and they do not seem to help me at all. I know where the problem is. Fetching lazy because the session is closed. I thought @Transactional
would help but it does not. And I know that I should not use the annotation in the controller. I will change that when I've fixed this problem. And I also will create a DTO instead of annotate the entity.
I got my entity MlpConfig and I want to send alle configs to my frontend. But the connections with other entities make this problems:
Could not write JSON: could not initialize proxy [com.project.data.ActivationFunction#4] - no Session; nested exception is com.fasterxml.jackson.databind.JsonMappingException: could not initialize proxy...
I need all informations (ActivationFunction, Layers) in the response and I really don't want to fetch EAGER. Even though I set it to EAGER in MlpConfig
, ActivationFunction
will complain about the same problem (cause of the connection to MlpConfig
)
The entity MlpConfig
(with @JsonIgnore
on all foreign objects the response works):
@Entity
@Data
@NoArgsConstructor
public class MlpConfig {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private long id;
@NotBlank(message = "Name for the MlpConfig is required")
@Column(name = "name", nullable = false, length = 255)
private String name;
private String description;
@NotNull(message = "Batch Size is required")
private int batchSize;
@NotNull(message = "Epoch Number is required")
private int epochNumber;
@EqualsAndHashCode.Exclude
@ToString.Exclude
@ManyToOne(fetch = FetchType.LAZY)
private ActivationFunction activationFunction;
@JsonIgnore
@OneToMany(mappedBy = "mlpConfig", orphanRemoval = true)
private Set<Layer> layers = new HashSet<>();
@JsonIgnore
@EqualsAndHashCode.Exclude
@ToString.Exclude
@ManyToOne(fetch = FetchType.LAZY)
private User user;
private Timestamp lastUpdated;
public MlpConfig(String name, String description, int batchSize, int epochs, Set<Layer> layers,
ActivationFunction activationFunction, User user) {
this.name = name;
this.description = description;
this.batchSize = batchSize;
this.epochNumber = epochs;
this.activationFunction = activationFunction;
this.layers = layers;
this.lastUpdated = Timestamp.from(Instant.now());
this.user = user;
}
The call of the method:
@Transactional
@GetMapping("/getAllConfigs")
public ResponseEntity<Object> getAllMlpConfig(@RequestHeader HttpHeaders headers, Authentication authentication) {
User user = userService.findByUsername(authentication.getName());
List<MlpConfig> configs = mlpConfigService.findAllByUser_id(user.getId());
return ResponseEntity.status(HttpStatus.OK).body(configs);
}
The entity ActivationFunction
:
@Entity
@Data
@NoArgsConstructor
@Table(name = "activationFunctions")
public class ActivationFunction {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer id;
@Enumerated(EnumType.STRING)
@Column(length = 20)
private EActivationFunction type;
@ToString.Exclude
@OneToMany(mappedBy = "activationFunction")
private Set<MlpConfig> mlpConfig;
public ActivationFunction(EActivationFunction type) {
this.type = type;
}
}
So how to handle this? I just found this one solution for Spring MVC with seems very old.