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.
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); } }; }
Advertisement
Answer
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).