Home > Enterprise >  Spring jpa repository returns the entity class instead of the dto interface
Spring jpa repository returns the entity class instead of the dto interface

Time:12-09

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.

  • Related