【问题标题】:LazyLoading prevents RestController from returning the correct values延迟加载会阻止 Rest Controller 返回正确的值
【发布时间】:2018-03-23 00:28:01
【问题描述】:

我认为 Hibernate 的延迟加载可能会阻止我的控制器返回适当的响应。

@RestController
@RequestMapping("/shifts")
public class ShiftController {
    private ShiftService shiftService;

    @Autowired
    public ShiftController(ShiftService shiftService) {
        this.shiftService = shiftService;
    }

    @GetMapping("")
    @PreAuthorize("hasAnyAuthority('ADMIN','SUPERVISOR')")
    Collection<Shift> getShifts() {
        return shiftService.fetchAll();
    }

    @GetMapping("/{id}")
    @PreAuthorize("hasAnyAuthority('ADMIN','SUPERVISOR')")
    ResponseEntity<Shift> getOneShift(@PathVariable("id") Long id) {
        Shift shift = shiftService.fetchOne(id);
        return new ResponseEntity<>(shift, HttpStatus.OK);
    }
}

班次

@Entity
public class Shift {
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    @Column(name = "SHIFT_ID")
    private Long id;

    @Column(name = "START", nullable = false)
    private OffsetDateTime start;

    @Column(name = "END", nullable = false)
    private OffsetDateTime end;

    @ManyToOne(optional = false, fetch = FetchType.EAGER)
    @JoinColumn(name = "USER_ID", nullable = false)
    private User user;

    @ManyToOne(optional = false, fetch = FetchType.EAGER)
    @JoinColumn(name = "TASK_ID", nullable = false)
    private Task task;
}

在不调试的情况下运行测试时,我得到以下响应(Body 为 NULL)。

MockHttpServletResponse:
           Status = 200
    Error message = null
          Headers = {Content-Type=[application/json;charset=UTF-8], X-Content-Type-Options=[nosniff], X-XSS-Protection=[1; mode=block], Cache-Control=[no-cache, no-store, max-age=0, must-revalidate], Pragma=[no-cache], Expires=[0], X-Frame-Options=[DENY]}
     Content type = application/json;charset=UTF-8
             Body = null
    Forwarded URL = null
   Redirected URL = null
          Cookies = []

当我在ShiftController 中的Shift shift = shiftService.fetchOne(id); 行添加断点时,跳过,然后继续,我得到了我想要的响应(Body Exists)。

MockHttpServletResponse:
           Status = 200
    Error message = null
          Headers = {Content-Type=[application/json;charset=UTF-8], X-Content-Type-Options=[nosniff], X-XSS-Protection=[1; mode=block], Cache-Control=[no-cache, no-store, max-age=0, must-revalidate], Pragma=[no-cache], Expires=[0], X-Frame-Options=[DENY]}
     Content type = application/json;charset=UTF-8
             Body = {"id":2,"start":"2018-03-22T17:17:57.387-07:00","end":"2018-03-22T17:17:57.389-07:00","user":{"id":1,"username":"testuser","email":null,"role":"STUDENT"},"task":{"id":1,"name":"CLEANUP"}}
    Forwarded URL = null
   Redirected URL = null
          Cookies = []

一些谷歌搜索让我相信问题源于 Hibernate 的延迟加载。有什么办法解决这个问题?

编辑:忘记添加 shiftService.fetchOne() 方法只是包装了 JpaRepository's getOne() 方法。

【问题讨论】:

    标签: spring hibernate spring-mvc spring-boot


    【解决方案1】:

    这似乎是你问题的罪魁祸首。

    忘记添加 shiftService.fetchOne() 方法只是包装了 JpaRepository 的 getOne() 方法。

    getOne 方法仅返回来自DB(延迟加载) 的引用。所以基本上你在事务之外(不考虑你在服务类中声明的事务),因此延迟加载的响应时间很慢。

    您应该在shiftService.fetchOne() 实现中使用findOne() JPA API,而不是getOne()

    查看API文档here

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2020-01-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多