Spring jpa 存储库 returns 实体 class 而不是 dto 接口

Spring jpa repository returns the entity class instead of the dto interface

我在后端代码中使用 Spring 数据 jpa。我已经包含了实体、dto 接口、服务和 jpa 存储库代码。

现在的问题是,当我在 TopicService 中调用 getAllTopics() 时。它 return 是 Topic 对象的列表而不是 TopicDtoTopic 对象包含 examples 的列表,我没有将其包含在 TopicDto 中。并且 Topic 对象还包括 Comment 对象列表而不是 CommentDto.

只有当我在 TopicDto 中添加 Set<CommentDto> getComments() 时才会发生这种情况。如果我删除它,一切正常。谁能告诉我应该如何在我的服务和存储库 class 中映射 dto?为什么它 return entity class 而不是 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;
   } 
}

– 存储库管理的域类型 – 存储库管理的实体的 id 类型

所以这对 return 领域对象来说是正常的。您指定了@Entity 主题 Class.

希望回答对您有所帮助。

首先是将您的 TopicRepository 更改为使用 Topic 实际实体,而不是 TopicDto:

public interface TopicRepository extends JpaRepository<Topic, Long> {   
    List<Topic> findAllBy(Sort sort);
}

那么,你需要以下DTO 类:

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;
    }
}

最后,在您的 TopicService 中,您需要进行从 TopicTopicDto 的映射,如下所示:

@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());
   } 
}