我不知道哪里有人报告java bug。我可以诚实地说我以前从未见过。但是 hibernate 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;
}
结束编辑
子表:
@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 甚至不打印日志语句。
// 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())
结果符合预期。所以很明显hibernate和Java 11之间存在加载问题。
最佳答案
我不知道为什么这适用于 Java 8 或为什么第二个 foreach
有效。
但是paramsList()
正在直接访问字段params
。 Hibernate 将延迟加载附加到 getters,但由于没有 getters,这不起作用。
如果您将 paramsList()
重命名为 getParams()
,Hibernate 应该将其检测为 getter 并执行适当的延迟加载。
关于java - Hibernate 延迟加载不适用于 java 11 中的 forEach(),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56275822/