Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

JPA Lazy loading is not working in Spring boot

I googled a lot and It is really bizarre that Spring Boot (latest version) may not have the lazy loading is not working. Below are pieces of my code:

My resource:

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

My service:

@Service
@Transactional
public class AirWaybillService {

//Methods

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

My Entity:

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

And when debugging, I still getting all lazy loaded attributed loaded. See image below.

enter image description here

One of my questions is could Jackson be involved in such behaviour? Is there any way that I may have missed to activate the lazy loading?

EDIT

Another question, could the debugger be involved in ruining the lazy loading?

EDIT 2:

For specification build, I have :

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);
        }
    };
}
like image 706
Houssem Badri Avatar asked Apr 16 '19 07:04

Houssem Badri


People also ask

How lazy loading works in JPA?

lazy it is interpreted as a hint to the jpa provider that the loading of that field may be delayed until it is accessed for the first time: the property value in case of a @basic annotation, the reference in case of a @manytoone or a @onetoone annotation, or.

How lazy loading works in spring boot?

By default in Spring, all the defined beans, and their dependencies, are created when the application context is created. In contrast, when we configure a bean with lazy initialization, the bean will only be created, and its dependencies injected, once they're needed.

What is lazy loading in Spring JPA?

With a LAZY type dependency, only data of the wanted object is loaded: author's data is not retrieved. With Spring Data JPA, every relationship between 2 domain objects owns one of these data loading types. By default, the method will be determined by the relationship type.

How do you initialize a lazy load?

Implementing a Lazy-Initialized Property To implement a public property by using lazy initialization, define the backing field of the property as a Lazy<T>, and return the Value property from the get accessor of the property. The Value property is read-only; therefore, the property that exposes it has no set accessor.


2 Answers

Hibernate Session exists within method with @Transactional. Passing entity outside Service class is a bad practise because session is being closed after leaving your search method. On the other hand your entity contains lazy initialised collections, which cannot be pulled once session is closed.

The good practise is to map entity onto transport object and return those transport objects from service (not raw entities).

like image 144
Tomasz Białecki Avatar answered Sep 28 '22 05:09

Tomasz Białecki


When using a debugger, you are trying to access the value of your variables. So, at the moment you click that little arrow on your screen, the value of the variable in question is (lazily) loaded.

like image 33
Sofo Gial Avatar answered Sep 28 '22 03:09

Sofo Gial