Я нашел решение своей проблемы после долгих поисков и испытаний и с помощью @marnish и @ Augusto.
Мне нужно начать с вопроса, что я неправильно задал свой вопрос, потому что я хотел знать, как я могу внедрить эти данные в свою сущность, в то время как такой образ мыслей заставлял меня испытывать большие трудности с поиском решения, потому что это ограничено тем, чего я смог достичь. Лучше было отделить мой объект базы данных от моих объектов JSON, потому что один предназначен для сохранения данных, другой для представления клиенту и первый способ практически не связан со столбцами базы данных. Переходные свойства не были здесь решением и для меня.
Понимая (и принимая) это, следующая проблема состояла в том, чтобы заставить новый объект презентации хорошо играть с упаковщиками страниц, потому что мне нужно было разбивать страницы на свои Вопросы. Вот что я написал в качестве решения:
Вопрос как сущность, связанная с таблицей базы данных и столбцами
@Entity
@Table(name = "vragen")
// BaseEntity just contains the ID property
public class Question extends BaseEntity {
@Column(name = "vraag")
private String question;
@Column(name = "bericht")
private String message;
@ManyToOne
@JoinColumn(name = "gebruiker")
private User user;
@Column(name = "beantwoord", insertable = false)
private boolean answered;
@Column(name = "gepost_op", insertable = false)
private Timestamp postedOn;
@Column(name = "actief", insertable = false)
@JsonIgnore
private boolean active;
@Column(name = "bekeken", insertable = false, updatable = false)
private int viewed;
@ManyToMany(fetch = FetchType.EAGER)
@JoinTable(
name = "vragen_tags",
joinColumns = @JoinColumn(name = "vraag_id", referencedColumnName = "id"),
inverseJoinColumns = @JoinColumn(name = "tag_id", referencedColumnName = "id"))
private Set<Tag> tags;
@OneToMany(mappedBy = "question")
// Thanks to @manish we can do it more efficiently instead of loading all the Answer objects
@LazyCollection(LazyCollectionOption.EXTRA)
@JsonManagedReference
private Set<Answer> answers;
public Question() {}
// getters and setters
}
QuestionDTO как объект представления JSON
public class QuestionDTO {
private Integer id;
private String question;
private String message;
private User user;
private boolean answered;
private Timestamp postedOn;
private int viewed;
private Set<Tag> tags;
private int totalAnswers;
public QuestionDTO() {}
// getters and setters
}
Метод в QuestionServiceImpl:
public Page<QuestionDTO> getAllQuestions(int page, int size, String filter) {
List<QuestionDTO> questions = new ArrayList<>();
Page<Question> questionPage;
switch (filter) {
case "popular":
questionPage = questionRepository.findAllByActiveTrueOrderByViewedDescPostedOnDesc(PageRequest.of(page, size));
break;
case "answered":
questionPage = questionRepository.findAllByActiveTrueAndAnsweredTrueOrderByPostedOnDesc(PageRequest.of(page, size));
break;
default:
questionPage = questionRepository.findAllByActiveTrueOrderByPostedOnDesc(PageRequest.of(page, size));
break;
}
// Here the entity data is being converted to the presentation DTO. I'm sure this can be done cleaner with for example Mapstruct as objectmapper.
for (Question q : questionPage) {
QuestionDTO questionDTO = new QuestionDTO();
questionDTO.setId(q.getId());
questionDTO.setQuestion(q.getQuestion());
questionDTO.setMessage(q.getMessage());
questionDTO.setUser(q.getUser());
questionDTO.setAnswered(q.isAnswered());
questionDTO.setPostedOn(q.getPostedOn());
questionDTO.setViewed(q.getViewed());
questionDTO.setTags(q.getTags());
questionDTO.setTotalAnswers(q.getAnswers().size());
questions.add(questionDTO);
}
// We want to keep all the pagination data that the method returned, so we need to wrap the questionDTO in a Page wrapper and pass all the data from Page<Question>
return new PageImpl<>(questions, questionPage.getPageable(), questionPage.getTotalElements());
}
Ответный субъект:
@Entity
@Table(name = "antwoorden")
public class Answer extends BaseEntity {
@Column(name = "bericht")
private String message;
@ManyToOne
@JoinColumn(name = "gebruiker")
private User user;
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "vraag")
@JsonBackReference
private Question question;
@Column(name = "gepost_op", insertable = false)
private Timestamp postedOn;
@Column(name = "actief", insertable = false)
private boolean active;
public Answer() {}
// getters and setters
}