我不知道在哪里报告Java错误。老实说,我从未见过。但是休眠的JPA和Java foreach的延迟加载在Java 11.0.2中不起作用。我没有看到它在11.0.3中被列为固定版本,但是没有进行测试。
它在Java 8中确实有效。因此,我想买家要当心!
框架: Spring Boot 2.1.1(Spring 5.1.3) Hibernate 5.3.7.Final
开始编辑 部分父模型:
@Entity
@Table(name = "REST_ENDPOINT")
public class RestEndpoint extends AuditModel {
private String endpointName;
private String httpVerb;
private String httpTemplate;
private String serviceName;
...
@OneToMany(mappedBy = "restEndpoint", cascade = CascadeType.ALL, orphanRemoval = true)
public List<RestEndpointParam> params = new ArrayList<>();
public void addRestEndpointParam(RestEndpointParam param) {
params.add(param);
param.setRestEndpoint(this);
}
public void removeRestEndpointParam(RestEndpointParam param) {
params.remove(param);
param.setRestEndpoint(null);
}
public void setParams(List<RestEndpointParam> params) { this.params = params; }
public List<RestEndpointParam> paramsList() {
return params;
}
END EDIT
子表:
@Entity
@Table(name = "REST_ENDPOINT_PARAM")
public class RestEndpointParam {
...
private Long endpointId;
private RestEndpoint restEndpoint;
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "ENDPOINT_ID", insertable = false, updatable = false)
public RestEndpoint getRestEndpoint() { return restEndpoint; }
现在是最恐怖的部分。子表中有2个项目,第一个foreach甚至不会打印log语句。
// First set up the URI replacement variables
restEndpoint.paramsList().forEach(restEndpointParam -> {
logger.warn("ENDPOINT 1st forEach access PARAM:{}", restEndpointParam.getType());
if (restEndpointParam.getType().equals("URI")) {
uriParams.put(restEndpointParam.getKey(), restEndpointParam.getValue());
}});
// Now apply the Query parameters
restEndpoint.paramsList().forEach(restEndpointParam -> {
logger.warn("ENDPOINT 2nd foreach access PARAM:{}", restEndpointParam.getType());
if (restEndpointParam.getType().equals("QUERY")) {
builder.queryParam(restEndpointParam.getKey(), restEndpointParam.getValue());
}});
第二forEach正常工作。因此,这是第一个失败的参考。还用常规循环替换了第一次访问(forEach):
for (RestEndpointParam restEndpointParam : restEndpoint.paramsList())
结果符合预期。因此很明显,休眠和Java 11之间存在加载问题。
答案 0 :(得分:0)
我不知道为什么它可以与Java 8一起使用,或者为什么第二个foreach
可以工作。
但是paramsList()
正在直接访问字段params
。 Hibernate将延迟加载附加到getter上,但是由于没有getter,这是行不通的。
如果将paramsList()
重命名为getParams()
,Hibernate应该将其检测为吸气剂并执行适当的延迟加载。