0

I've generated a simple app with JHipster. I have several entities which are in relationships. For example, I have an IndexPage which contains several IndexAreas. Each IndexArea can contain several IndexTiles. Each IndexTile is connected to one CoursePage.

By default I had @JsonIgnore annotation at the @OneToMany sides, but that meant I cannot display all the elements in the frontend (because I don't see them). For example, I can edit an IndexTile and pick an IndexArea from the dropdown list, but I can't do ng-repeat through the IndexTiles in an IndexArea, because they are not in the JSON.

If I remove @JsonIgnore, I would get an infinite recursion (that was expected). So I replaced all the @JsonIgnores with @JsonSerialize(using = MyCustomSerializer.class). Here is the current state that I have:

public class IndexPage {
...
  @OneToMany(mappedBy = "indexPage")
  @JsonSerialize(using = IndexAreaSerializer.class)
  private Set<IndexArea> indexAreas = new HashSet<>();
...
}

public class IndexArea {
...
  @ManyToOne
  private IndexPage indexPage;

  @OneToMany(mappedBy = "indexArea")
  @JsonSerialize(using = IndexTileSerializer.class)
  private Set<IndexTile> indexTiles = new HashSet<>();
...
}

public class IndexTile{
  ...
  @ManyToOne
  private IndexArea indexArea;

  @OneToOne
  @JoinColumn(unique = true)
  private CoursePage coursePage;
  ...
}

public class CoursePage {
  ...
  @OneToOne(mappedBy = "coursePage")
  @JsonIgnore // a CoursePage doesn't care about the indexTile
  private IndexTile indexTile;
  ...
}

Now when I refresh my page, I get an error:

org.springframework.http.converter.HttpMessageNotWritableException: Could not write JSON: failed to lazily initialize a collection of role: rs.kursnemackog.domain.IndexPage.indexAreas, could not initia
lize proxy - no Session; nested exception is com.fasterxml.jackson.databind.JsonMappingException: failed to lazily initialize a collection of role: rs.kursnemackog.domain.IndexPage.indexAreas, could no
t initialize proxy - no Session (through reference chain: rs.kursnemackog.domain.IndexPage["indexAreas"])

What can I do in order to be able to see both sides of the relation and to use them normally (e.g. to be able to pick an IndexArea for an IndexTile and also to ng-repeat through all the IndexTiles in a certain IndexArea)?

Thanks.

vtomic85
  • 590
  • 1
  • 11
  • 32

1 Answers1

1

Lazy loading exception is normal because JHipster declares all relationships as lazy loaded which is considered as a good practice. The exception is due to lack of session because it is done as the time of the JSON serialization so after your transaction has been closed in service or repository layer.

There are several solutions like extending the scope of transaction with @Transactional or open-session-in-view property but it's usually better to modify your repository to eager fetch your relationship either using @EntityGraph or in query language.

More hints here: How does the FetchMode work in Spring Data JPA

Additionally, you might want to use DTOs and Service class options in JHipster to avoid exposing your entities in your REST API and get more control about the objects consumed by your Angular app.

Gaël Marziou
  • 16,028
  • 4
  • 38
  • 49