Hibernate Ленивая загрузка не работает с forEach () в Java 11 - PullRequest
1 голос
/ 23 мая 2019

Я не знаю, где сообщают об ошибках Java.Я могу честно сказать, что никогда раньше не видел ни одного.НО ленивая загрузка 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 даже не печатает инструкцию 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())

Результаты ожидаемые.Очевидно, что существует проблема загрузки между hibernate и Java 11.

1 Ответ

0 голосов
/ 24 мая 2019

Понятия не имею, почему это работает с Java 8 или почему работает второй foreach.

Но paramsList() напрямую обращается к полю params. Hibernate прикрепляет ленивую загрузку к получателям, но так как нет получателей, это не работает.

Если вы переименуете paramsList() в getParams(), Hibernate должен определить его как геттер и выполнить ленивую загрузку с проппером.

...