java - Hibernate 延迟加载不适用于 java 11 中的 forEach()

标签 java hibernate spring-data-jpa java-11

我不知道哪里有人报告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/

相关文章:

java - Weblogic 12c 服务器是否忽略 http.proxy* 参数?

java - Spring + Hibernate 动态映射

java - bean类[org.springframework.transaction.interceptor.TransactionInterceptor]的无效属性 'transactionManagerBeanName'

rest - 如何将 PageRequest 对象转换为查询字符串?

java - 不能从静态上下文中引用非静态变量 x

java - 是否可以将所有请求路由到单个 servlet?

java - 如何将移位元素函数与插入排序结合起来?

java - hibernate 的奇怪行为

java - 我应该使用 Java 8 默认方法来手动实现 Spring Data 存储库方法吗?

postgresql - 我如何使用 JPA native 查询更新点类型数据?