web-dev-qa-db-fra.com

Le chargement paresseux JPA ne fonctionne pas dans Spring Boot

J'ai beaucoup cherché sur Google et c'est vraiment bizarre que Spring Boot (dernière version) n'ait pas le chargement paresseux qui ne fonctionne pas. Voici des morceaux de mon code:

Ma ressource:

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

Mon service:

@Service
@Transactional
public class AirWaybillService {

//Methods

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

Mon entité:

@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;
}

Et lors du débogage, je reçois toujours tous les paresseux chargés. Voir l'image ci-dessous.

enter image description here

L'une de mes questions est la suivante: Jackson pourrait-il être impliqué dans un tel comportement? Est-il possible que j'aie manqué d'activer le chargement paresseux?

[~ # ~] modifier [~ # ~]

Une autre question, le débogueur pourrait-il être impliqué dans la ruine du chargement paresseux?

EDIT 2:

Pour la spécification build, j'ai:

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
Houssem Badri

Lorsque vous utilisez un débogueur, vous essayez d'accéder à la valeur de vos variables. Donc, au moment où vous cliquez sur cette petite flèche sur votre écran, la valeur de la variable en question est (paresseusement) chargée.

1
Sofo Gial

Très probablement, vous déboguez tout en étant à l'intérieur du service, donc pendant que la transaction est encore active et que le chargement différé peut être déclenché (toute méthode appelée sur un élément paresseux a déclenché la récupération à partir de la base de données).

Le problème est que le chargement différé ne peut pas se produire en dehors de la transaction. Et Jackson analyse définitivement votre entité en dehors des limites d'une entité.

Vous devez soit récupérer toutes les dépendances requises lors de la construction de votre spécification, soit essayer avec le @Transactional au niveau des ressources (mais essayez cela en dernier recours).

Juste pour que vous le sachiez, la stratégie de récupération LAZY n'est qu'un indice .. pas une action obligatoire. Désireux est obligatoire:

La stratégie LAZY indique au moteur d'exécution du fournisseur de persistance que les données doivent être récupérées paresseusement lors de leur premier accès. L'implémentation est autorisée à récupérer avec impatience les données pour lesquelles l'indicateur de stratégie LAZY a été spécifié.

1
Maciej Kowalski

Juste une supposition: vous forcez une extraction lors de la construction de votre spécification.

J'attends quelque chose comme

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

Si tel est le cas, essayez de modifier root.fetch à root.join

1
Lesiak

Les données récupérées sont déjà paresseuses mais vous utilisez le mode débogage sa valeur de retour lorsque vous cliquez sur pour regarder les données d'un débogueur.

0
Muhammed Atallah