skip to Main Content

What I have in my hands are 4 deeply related entities.

The first one is Sickness defined as follows:

public class Sickness {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "id", nullable = false)
    @JsonView(Views.Superficial.class)
    private Long id;
/*
* ...
*/
    @OneToMany(fetch = FetchType.LAZY)
    private List<Diagnostic> Diagnostic; // <---- The first problem :)
/*
*...
*/

Now the diagnostic for the sickness is defined as followed

@Entity
/*
* ...
*/
@Table(name = "Diagnostic")
public class Diagnostic{

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @JsonView(Views.Superficial.class)
    private Long id;
/*
*...
*/
    @JsonIgnore
    private String label;

    @ManyToMany(fetch = FetchType.EAGER)
    @JsonView(Views.Detailed.class)
    private List<Question> questions; // <-- Second Problem !

    @JsonIgnore
    @ManyToOne(fetch = FetchType.LAZY)
    private Sickness sickness;

The question Entity is defined like this :

@Entity
@NoArgsConstructor
@AllArgsConstructor
@Getter
@Builder
@Setter
@Table(name = "question")
public class Question {
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    @Column(name = "id", nullable = false)
    @JsonView(Views.Superficial.class)
    private Long id;

    @Enumerated
    @JsonView(Views.Superficial.class)
    private TypeQuestion type;

    @JsonView(Views.Superficial.class)
    private String question_label;

    @ManyToMany
    @JsonView(Views.Superficial.class)
    private List<Choice> choiceList; // <-- Third problem XD

And finally the Choice entity is defined as such :

@Entity
@AllArgsConstructor
@NoArgsConstructor
@Getter
@Setter
@Builder
@Table(name = "choice")
public class Choice {

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    @JsonView(Views.Superficial.class)
    private Long id;

    @JsonView(Views.Superficial.class)
    private String label;

    @OneToOne
    @JsonView(Views.Detailed.class)
    private Diagnostique diagnostique; // <-- :) ; did this because you could have multiple 
                                       // diacnostics for a sickness symtome 

    @OneToOne
    @JsonView(Views.Superficial.class)
    private Traitement traitement; 

    @JsonView(Views.Superficial.class)
    private String noTreatementNoDiagnosticChoice;
}

The problem is probably the Choice entity since it calls the diagnostic entity recursively in one or two records.

I have manually injected data records, now it works for the case where I have a single nested diagnostic entity in the Choice object (Diagnostic -> Question -> Choice -> Diagnostic -> Question -> Choice -> Treatment)

But for the double nested case it throws that error (Diagnostic -> Question -> Choice -> Diagnostic -> Question -> Choice Diagnostic -> Question -> Choice -> Treatment ).

I really don’t know what to do at this point, the data modeling of the case is not that great and I’m really too invested in this version of modeling to change it.

Can anyone help?

Here’s some stack traces:

When I query the Sickness

org.springframework.http.converter.HttpMessageNotWritableException: Could not write JSON: 4; nested exception is com.fasterxml.jackson.databind.JsonMappingException: 4rntat org.springframework.http.converter.json.AbstractJackson2HttpMessageConverter.writeInternal(AbstractJackson2HttpMessageConverter.java:465)rntat org.springframework.http.converter.AbstractGenericHttpMessageConverter.write(AbstractGenericHttpMessageConverter.java:104)rntat org.springframework.web.servlet.mvc.method.annotation.AbstractMessageConverterMethodProcessor.writeWithMessageConverters(AbstractMessageConverterMethodProcessor.java:290)rntat org.springframework.web.servlet.mvc.method.annotation.HttpEntityMethodProcessor.handleReturnValue(HttpEntityMethodProcessor.java:219)rntat 

When I query the diagnostic

org.springframework.http.converter.HttpMessageNotWritableException: Could not write JSON: 4; nested exception is com.fasterxml.jackson.databind.JsonMappingException: 4 (through reference chain: com.nst.onercp.domain.Diagnostic$HibernateProxy$SlDHxnlx["questions"])rntat org.springframework.http.converter.json.AbstractJackson2HttpMessageConverter.writeInternal(AbstractJackson2HttpMessageConverter.java:465)rntat org.springframework.http.converter.AbstractGenericHttpMessageConverter.write(AbstractGenericHttpMessageConverter.java:104)rntat org.springframework.web.servlet.mvc.method.annotation.AbstractMessageConverterMethodProcessor.writeWithMessageConverters(AbstractMessageConverterMethodProcessor.java:290)rntat org.springframework.web.servlet.mvc.method.annotation.HttpEntityMethodProcessor.handleReturnValue(HttpEntityMethodProcessor.java:219)rntat org.springframework.web.method.support.HandlerMethodReturnValueHandlerComposite.handleReturnValue(HandlerMethodReturnValueHandlerComposite.java:78)

Sorry for the long post 🙂

2

Answers


  1. Chosen as BEST ANSWER

    Solved with @JsonIgnoreProperties(value="diagnostique") and a dedicated api endpoint to get the diagnostic of a choice if present.


  2. You should use DTOs pattern

    https://en.wikipedia.org/wiki/Data_transfer_object

    Try learning about Mapstruct it might help with this use case

    https://mapstruct.org/

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search