【问题标题】:lazy loaded list of object in spring jpa transactional service is emptyspring jpa事务服务中的延迟加载对象列表为空
【发布时间】:2022-02-04 22:45:37
【问题描述】:

我在后端代码中使用 Spring data jpa。我已经包含了实体、服务和控制器代码。

示例代码很简单。主题和评论是OneToMany 关系。评论被配置为延迟加载。现在如果我打电话给updateTopic 来更新主题。在控制台中,我将看到一个从评论表中获取 cmets 列表的查询,然后它将更新主题表。但是 cmets 列表是空的,即使它确实有一些与主题相关的 cmets。

@Entity
@Table(name = "TOPIC")
@Data
@NoArgsConstructor
@AllArgsConstructor
public class Topic implements Serializable {

    @Id
    @GeneratedValue(strategy=GenerationType.IDENTITY)
    private Long id;
    
    @Column(name = "NAME", length = 45)
    @NotNull
    private String name;

    @OneToMany(
            fetch = FetchType.LAZY, 
            cascade = CascadeType.REMOVE,
            mappedBy = "topic"
        )
    private List<Comment> comments= new ArrayList<>();

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

   
}

@Service
@Transactional
public class TopicService {
   private final TopicRepository topicRepository ;

   public TopicService(TopicRepository topicRepository ) {
      this.topicRepository = topicRepository ;
   }

   public Topic updateTopic(Topic topic) {
      Topic newTopic = topicRepository.save(topic);
      System.out.println("from service: " + newTopic.getComments().size());
      return newTopic;
   } 
}

然后,如果我尝试从控制器获取 cmets,则注释列表不为空。在控制台中,它将显示更新查询,然后选择查询以获取 cmets 列表。我的问题是如何从服务类中延迟加载 cmets 列表?好像和transactional会话有关。


@RestController
@RequestMapping("/api")
public class TopicRestController {
  
   @PutMapping("/release/{id}")
   public Topic updateTopic(@PathVariable long id, @RequestBody Topic newTopic ) {
      return topicService.getTopicById(id)
         .map(topic-> {
            Topic t = topicService.updateTopic(newTopic);
            System.out.println("controller: " + topic.getComments().size());
         })
         .orElseThrow(() -> new CustomException("The topic with id: " + id + " cannot be found", HttpStatus.NOT_FOUND));
   }
   
  
}

【问题讨论】:

    标签: java spring-boot hibernate spring-data-jpa


    【解决方案1】:

    您必须以某种方式将它们映射到 DTO。 您可以在个人资料中查看我的文章以了解详细信息。 请不要使用 FetchType.EAGER,它会影响性能。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-08-24
      • 2019-09-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-04-27
      相关资源
      最近更新 更多