我在下面具有与Company
具有1:N
关系的CompanyFunds
的映射
@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
包含null
的companyFunds
,即LAZY加载在此之前工作正常。但是,在执行return companyResource;
的那一刻,Spring内部就会发生某些事情,并且会触发Select
的CompanyFund
语句。我调试了步骤,下面是负责此操作的代码(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
中所做的事情,因此调用了一些吸气剂(或其他东西)。
我注意到的另一件事是,仅当返回Resource<Company>
时才会出现此问题。如果我从控制器返回Company
,则不会发生任何意外情况。延迟加载工作正常。
由于我想延迟加载该实体,所以一些修复/黑客为我解决了这个问题(截至目前)。
@JsonIgnore
@OneToMany(mappedBy = "company")
private List<CompanyFund> companyFunds;
@JsonIgnore
阻止对LAZY加载的实体进行序列化。所以我想杰克逊是罪魁祸首。
这不是我的观点,只是做这件事的一种技巧。仍在等待Spring
小组的人答复。