Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Spring Data, JPA @OneToMany Lazy fetch not working in Spring Boot

I have @OneToMany relationship between FabricRoll and FabricDefect.

@OneToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY)
@JoinColumn(name = "fabric_roll_id", referencedColumnName = "fabric_roll_id")
private Set<FabricDefect> fabricDefects = new HashSet<>();

The problem is when I get FabricRoll by JpaRepository function

findAll()

the associate FabricDefect is also loaded.

I want to load only FabricRoll and FabricDefect should load when calling the function getFabricDefect()

FabricRollServiceImpl class

@Component
public class FabricRollServiceImpl implements IFabricRollService{
    @Autowired
    FabricRollRepository fabricRollRepository;

    @Transactional(propagation = Propagation.REQUIRED)
    @Override
    public List<FabricRoll> getAllFabricRoll() {
        FabricRoll fabricRoll1 = new FabricRoll();
        fabricRoll1.setBatchNo("34344");
        fabricRoll1.setLotNo("425");
        fabricRoll1.setPoNo("42");
        fabricRoll1.setRollLength(2343);
        fabricRoll1.setRollNo("356");
        fabricRoll1.setRollWidth(60);
        fabricRoll1.setStyleNo("354");

        FabricDefect fabricDefect = new FabricDefect();
        fabricDefect.setDefectNote("note");
        fabricDefect.setDefectPoint(3);
        fabricDefect.setSegment(3);
        fabricDefect.setYard(42);


        Set<FabricDefect> fabricDefects = new HashSet<>();
        fabricDefects.add(fabricDefect);


        fabricRoll1.setFabricDefects(fabricDefects);

        addFabricRoll(fabricRoll1);

        FabricRoll fabricRoll = null;


        return fabricRollRepository.findAll();
    }

@Override
public void addFabricRoll(FabricRoll fabricRoll) {
    fabricRollRepository.save(fabricRoll);
}

}

Break point: enter image description here

Console: enter image description here

like image 612
Atekur Rahman Avatar asked Oct 23 '17 07:10

Atekur Rahman


1 Answers

It seems to be a debugging artifact.

At debugging time, because the transaction is still open, the watched lazy loaded entity properties will be loaded at the breakpoint evaluation time.

To check the "production" behavior you should insert a em.detach statement just before the breakpoint or use logging (as suggested by Manza) and check em.getEntityManagerFactory().getPersistenceUnitUtil().isLoaded(fabricRoll1.fabricDefects()) returns false on the detached entity.

(remember to inject EntityManager for example by declaring @PersistenceContext private EntityManager em;)

like image 194
Mike F. Avatar answered Sep 21 '22 14:09

Mike F.