RestController:返回 Resource<> 使 FetchType.LAZY 表现为 FetchType.EAGER



我有以下映射,因为CompanyCompanyFunds1:N关系

@Entity
public class Company{
@Id
private Integer companyId;
private String name;
@OneToMany(mappedBy = "company")
private List<CompanyFund> companyFunds;
}
@Entity
public class CompanyFunds{
@Id
private Integer fundId;
private String name;
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "company_id")
private Company company;
}

我正在使用Spring-data-Jpa作为我的持久性层,以下是控制器和服务方法:

//controller
@GetMapping(value = "/{companyId}")
public Resource<Company> find(@PathVariable Integer companyId) {
Resource<Company> companyResource = companyService.find(companyId);
return companyResource;
}
//service
public Resource<CompanyTypeOther> find(Integer companyId) {
Company company =  companyRepository.findById(companyId);
return restResourceAssembler.toResource(company);
}

@Component
public class RestResourceAssembler implements ResourceAssembler<T, Resource<T>> {
private EntityLinks entityLinks;
public RestResourceAssembler(EntityLinks entityLinks) {
this.entityLinks = entityLinks;
}
@Override
public  Resource<T>  toResource(T entity) {
Resource<T> resource = new Resource<>(entity);
resource.add(entityLinks.linkToSingleResource(entity.getClass(), entity.getId()).withSelfRel());
return resource;
}
}

现在奇怪的是,直到return companyResource;(在控制器中(没有被执行,companyResource包含companyFundsnull,即LAZY加载在那之前工作正常。但是当return companyResource;执行的那一刻,弹簧内部有东西进入,CompanyFundSelect语句被触发。我调试了这些步骤,下面是负责此操作的代码(try块(:

public class ServletInvocableHandlerMethod extends InvocableHandlerMethod {
......
public void invokeAndHandle(ServletWebRequest webRequest, ModelAndViewContainer mavContainer,
........other code
try {
this.returnValueHandlers.handleReturnValue(
returnValue, getReturnValueType(returnValue), mavContainer, webRequest);
}
catch (Exception ex) {
if (logger.isTraceEnabled()) {
logger.trace(formatErrorForReturnValue(returnValue), ex);
}
throw ex;
}
}
.....
}

实体中没有声明toString(),也没有调用getCompanyFund()。无法理解 Spring 在用上面的returnValue做什么,以至于一些 getters(或其他东西(被调用。

我注意到的另一件事是,此问题仅在返回Resource<Company>时发生。如果我从控制器返回Company,则不会发生任何意外情况。延迟加载工作正常。

由于我想延迟加载实体,因此一些修复/黑客为我解决了问题(截至目前(。

@JsonIgnore
@OneToMany(mappedBy = "company")
private List<CompanyFund> companyFunds;

@JsonIgnore防止序列化延迟加载的实体。所以我想杰克逊是这里的罪魁祸首。

这不是我的观点,而只是做这件事的黑客。仍在等待团队Spring某人回复。

最新更新