Spring Data,JPA @OneToMany懒加载在Spring Boot中无法工作

17

我有 @OneToMany 的关系连接了 FabricRollFabricDefect

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

问题在于我通过JpaRepository函数获取FabricRoll时,关联的FabricDefect也会被加载。

我希望仅加载FabricRoll,并且只有当调用getFabricDefect()函数时才加载FabricDefect

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

}

断点: 图片描述

控制台: 图片描述


{btsdaf} - Azzabi Haythem
{btsdaf} - Manza
如果您删除@Transactional注解,您会发现会出现LazyInitializationException,这意味着集合没有被加载。 - Manza
这是同一个问题的答案 https://dev59.com/EVgQ5IYBdhLWcg3wi0o9#42584774 - Max Farsikov
4个回答

1

这似乎是一个调试工具。

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

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

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


0

我在这个教程中找到了解决方案。

你需要按照以下方式修改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;

你不需要在 getAllFabricRoll() 函数之前添加 @Transactional(propagation = Propagation.REQUIRED)


0

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

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

在这个问题中了解更多this


0

FabricDefect类:

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

FabricRoll 类:

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

集合默认是懒加载的,只有在调用getFabricDefects方法时,JPA才会查询数据库。 您可以通过启用日志来查看它。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接