Spring Data,JPA @OneToMany Lazy fetch在Spring Boot中不起作用

时间:2017-10-23 07:13:19

标签: spring hibernate spring-data-jpa lazy-loading

@OneToManyFabricRoll之间有FabricDefect个关系。

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

问题是当我通过FabricRoll函数

获得JpaRepository
  

的findAll()

还加载了关联FabricDefect

我只想加载FabricRoll,而FabricDefect应该在调用函数时加载getFabricDefect()

  

FabricRollServiceImpl类

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

}

断点: enter image description here

控制台: enter image description here

4 个答案:

答案 0 :(得分:0)

您不需要使用@JoinColumn,也不需要实例化fabricDefects

@OneToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY)
private Set<FabricDefect> fabricDefects ; 

this问题中查看更多内容。

答案 1 :(得分:0)

FabricDefect类:

@ManyToOne
@JoinColumn(name = "fabric_roll_id")
private FabricRoll roll;

FabricRoll类:

@OneToMany(mappedBy = "roll")
private Set<FabricDefect> fabricDefects;

默认情况下,集合是懒惰加载的,只有在调用方法getFabricDefects时,JPA才会查询数据库。 您可以自己查看启用日志记录。

答案 2 :(得分:0)

我在this tutorial找到了解决方案。

您必须修改FabricRoll OneToMany地图,如下所示:

@OneToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY, mappedBy = "fabricRoll")
private Set<FabricDefect> fabricDefects;

FabricDefect ManyToOne如下所示(如果您将fabric_roll_id字段包含在您的实体中,请务必将其删除:

@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "fabric_roll_id")
private FabricRoll fabricRoll;

您无需在@Transactional(propagation = Propagation.REQUIRED)功能之前添加getAllFabricRoll()

答案 3 :(得分:0)

这似乎是调试工件。

在调试时,由于事务仍处于打开状态,因此监视的延迟加载的实体属性将在断点评估时加载。

要检查“生产”行为,应在断点之前插入em.detach语句,或使用日志记录(如Manza所建议),并检查em.getEntityManagerFactory().getPersistenceUnitUtil().isLoaded(fabricRoll1.fabricDefects())对分离的实体是否返回false。

(例如,通过声明@PersistenceContext private EntityManager em;来注入EntityManager)