JPA Ленивая загрузка не работает в весенней загрузке - PullRequest
3 голосов
/ 16 апреля 2019

Я много гуглил и очень странно, что Spring Boot (последняя версия) может не иметь отложенной загрузки, не работает.Ниже приведены фрагменты моего кода:

Мой ресурс:

 public ResponseEntity<Page<AirWaybill>> searchAirWaybill(CriteraDto criteriaDto, @PageableDefault(size = 10) Pageable pageable{
airWaybillService.searchAirWaybill(criteriaDto, pageable);
        return ResponseEntity.ok().body(result);
}

Мой сервис:

@Service
@Transactional
public class AirWaybillService {

//Methods

 public Page<AirWaybill> searchAirWaybill(AirWaybillCriteriaDto searchCriteria, Pageable pageable){
    //Construct the specification
            return airWaybillRepository.findAll(spec, pageable);
   }
}

Моя сущность:

@Entity
@Table(name = "TRACKING_AIR_WAYBILL")
@JsonIdentityInfo(generator=ObjectIdGenerators.IntSequenceGenerator.class, property="@airWaybillId") //to fix Infinite recursion with LoadedAirWaybill class
public class AirWaybill{
//Some attributes
    @NotNull
    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "FK_TRACKING_CORPORATE_BRANCH_ID")
    private CorporateBranch corporateBranch;
}

И при отладке я все равно получаю все ленивые загруженные приписанные загруженные.См. Изображение ниже.

enter image description here

Один из моих вопросов - может ли Джексон быть вовлечен в такое поведение?Есть ли способ, который я мог пропустить, чтобы активировать отложенную загрузку?

РЕДАКТИРОВАТЬ

Еще один вопрос, может ли отладчик участвовать в разрушении отложенной загрузки?

РЕДАКТИРОВАТЬ 2:

Для спецификации сборка, у меня есть:

public static Specification<AirWaybill> isBranchAirWayBill(long id){
    return new Specification<AirWaybill>() {
        @Override
        public Predicate toPredicate(Root<AirWaybill> root, CriteriaQuery<?> query, CriteriaBuilder cb) {
            return cb.equal(root.join("corporateBranch",JoinType.LEFT).get("id"),id);
        }
    };
}

Ответы [ 6 ]

3 голосов
/ 16 апреля 2019

SpringBoot по умолчанию включен:
spring.jpa.open-in-view = true
Это означает, что транзакция всегда открыта. Попробуйте отключить его.
больше информации здесь

1 голос
/ 17 апреля 2019

Hibernate Session существует в методе с @Transactional. Передача сущности за пределы класса Service является плохой практикой, поскольку сеанс закрывается после выхода из вашего метода search. С другой стороны, ваша сущность содержит ленивые инициализированные коллекции, которые не могут быть извлечены после закрытия сессии.

Рекомендуется отображать сущность на транспортный объект и возвращать эти транспортные объекты из службы (не необработанные сущности).

1 голос
/ 16 апреля 2019

Просто предположение: вы заставляете выборку при создании спецификации.

Я ожидаю что-то вроде

static Specification<AirWaybill> buildSpec() {
    return (root, query, criteriaBuilder) -> {
       Join<AirWaybill, CorporateBranch> br = (Join) root.fetch("corporateBranch");
       return criteriaBuilder.equal(br.get("addressType"), 1);
    };
}

Если это так, попробуйте изменить root.fetch на root.join

1 голос
/ 16 апреля 2019

Скорее всего, вы отлаживаете, все еще находясь внутри службы, таким образом, когда транзакция все еще активна и может быть запущена отложенная загрузка (любой метод, вызываемый для отложенного элемента, запускает выборку из базы данных).

Проблема в том, что отложенная загрузка не может происходить, находясь вне транзакции. А Джексон определенно разбирает вашу сущность за пределами одной.

Вы должны либо получить все необходимые зависимости при построении спецификации, либо попробовать @Transactional на уровне ресурсов (но попробуйте это в крайнем случае).

Просто чтобы вы знали, стратегия LAZY fetching - это только подсказка ... а не обязательное действие. Стремление обязательно:

Стратегия LAZY - это подсказка для среды выполнения персистентного провайдера, которая данные должны извлекаться лениво при первом обращении к ним. Реализация разрешено охотно получать данные, для которых ленивый был указан совет по стратегии.

1 голос
/ 16 апреля 2019

При использовании отладчика вы пытаетесь получить доступ к значению ваших переменных.Итак, в тот момент, когда вы нажимаете эту маленькую стрелку на экране, значение рассматриваемой переменной загружается (лениво).

0 голосов
/ 16 апреля 2019

Полученные данные уже ленивые, но вы используете режим отладки, его возвращаемое значение при нажатии для просмотра данных из отладчика.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...