我有以下映射,因为Company
与CompanyFunds
有1: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
包含companyFunds
null
,即LAZY加载在那之前工作正常。但是当return companyResource;
执行的那一刻,弹簧内部有东西进入,CompanyFund
的Select
语句被触发。我调试了这些步骤,下面是负责此操作的代码(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
某人回复。