I am using Spring data jpa in the backend codes. I have included entities, dto interfaces, service and jpa repository codes.
Now the issue is that when I call getAllTopics()
in the TopicService
. It returns a list of Topic
object instead of TopicDto
. Topic
object includes a list of examples
which I do not include in the TopicDto
. And Topic
object also includes a list of Comment
object instead of CommentDto
.
This only happens when I add Set<CommentDto> getComments()
in TopicDto
. If I remove it, everything work fine. Can anyone tell me how should I map the dto in my service and repository class? Why does it return entity class instead of dto?
@Entity
@Table(name = "TOPIC")
@Data
@NoArgsConstructor
@AllArgsConstructor
public class Topic implements Serializable {
@Id
@GeneratedValue(strategy=GenerationType.IDENTITY)
private Long id;
@OneToMany(
fetch = FetchType.LAZY,
cascade = CascadeType.REMOVE,
mappedBy = "topic"
)
private Set<Comment> comments= new HashSet<>();
@OneToMany(
fetch = FetchType.LAZY,
cascade = CascadeType.REMOVE,
mappedBy = "topic"
)
private Set<Example> examples = new HashSet<>();
}
@Entity
@Table(name = "COMMENT")
@Data
@NoArgsConstructor
@AllArgsConstructor
public class Comment implements Serializable {
@Id
@GeneratedValue(strategy=GenerationType.IDENTITY)
private Long id;
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "Topic_ID")
private Topic topic;
@OneToMany(
fetch = FetchType.LAZY,
cascade = CascadeType.REMOVE,
mappedBy = "comment"
)
private Set<AnotherExample> anotherExamples = new HashSet<>();
}
public interface TopicDto{
Long getId();
Set<CommentDto> getComments();
}
public interface CommentDto{
Long getId();
}
public interface TopicRepository extends JpaRepository<Topic, Long> {
List<TopicDto> findAllBy(Sort sort);
}
@Service
@Transactional
public class TopicService {
private final TopicRepository topicRepository ;
public TopicService(TopicRepository topicRepository ) {
this.topicRepository = topicRepository ;
}
@Transactional(readOnly = true)
public List<TopicDto> getAllTopics(Sort sort) {
List<TopicDto> l = topicRepository.findAllBy(sort);
return l;
}
}
CodePudding user response:
First thing is to change your TopicRepository
to use Topic
, the actual entity, and not TopicDto
:
public interface TopicRepository extends JpaRepository<Topic, Long> {
List<Topic> findAllBy(Sort sort);
}
Then, you need the following DTO classes:
import java.util.HashSet;
import java.util.Set;
public class TopicDto {
private Long id;
private Set<CommentDto> comments= new HashSet<>();
public TopicDto(Long id, Set<CommentDto> comments) {
this.id = id;
this.comments = comments;
}
}
public class CommentDto {
private Long id;
public CommentDto(Long id) {
this.id = id;
}
}
Finally, in your TopicService
you need to do the mapping from Topic
to TopicDto
as follows:
@Service
@Transactional
public class TopicService {
private final TopicRepository topicRepository ;
public TopicService(TopicRepository topicRepository ) {
this.topicRepository = topicRepository ;
}
@Transactional(readOnly = true)
public List<TopicDto> getAllTopics(Sort sort) {
List<Topic> topics = topicRepository.findAllBy(sort);
return topics.stream()
.map(topic -> {
Set<CommentDto> commentsDto = topic.getComments().stream()
.map(comment -> new CommentDto(comment.getId()))
.collect(Collectors.toSet());
return new TopicDto(topic.getId(), commentsDto);
})
.collect(Collectors.toList());
}
}
CodePudding user response:
– the domain type the repository manages – the type of the id of the entity the repository manages
so that is normal to return domain object. You specified @Entity the Topic Class.
I hope the answer was helpful.