首页 > 解决方案 > @Scheduled 和 @Transactional 方法中的 Spring-data-jpa 延迟加载

问题描述

在我的配置类中,我需要将方法作为 cronjob 运行。所以我使用@Scheduled注解创建了一个方法。

@Scheduled(initialDelay = 10 * 1000, fixedRate = 1000 * 1000)
public void ThemeUpdate() {
    List<ThemeIndex> indices = getServices();
    ...
}

ThemeUpdate()方法现在在它自己的线程中运行,我将丢失我的事务。所以我使用@Transactional注释创建了另一种方法。

@Transactional
public List<ThemeIndex> getServices() {
    List<Service> services = serviceRepository.findServices();

    Section section = services.get(0).getSections().iterator().next();

    return null;
}

List<Service> services从我的serviceRepository. 但是,如果我想访问通过延迟加载获取的 a SectionEntity为什么我会得到 a LazyInitializationException

org.hibernate.LazyInitializationException: failed to lazily initialize a collection of role: com.example.myPorject.db.model.Service.sections, could not initialize proxy - no Session

我在这里想念什么?

编辑:

预定:

@Scheduled(initialDelay = 10 * 1000, fixedRate = 10000 * 1000)
@Transactional
public void ThemeUpdate() {
    List<ThemeIndex> indices = themeUpdateServiceImpl.getIndices();
}

获取索引():

@Override
public List<ThemeIndex> getIndices() {
    return getIndices(serviceRepository
        .findServices());
}

@Override
public List<ThemeIndex> getIndices(List<Service> services) {
    return themeIndexServiceImpl.getThemeIndexes(services);
}

获取主题索引():

@Override
public List<ThemeIndex> getThemeIndexes(List<Service> services) {
    List<ThemeIndex> themeIndexs = new ArrayList<>();
    for (Service s : services) {
        ThemeIndex themeIndex = getThemeIndex(s);
        if (themeIndex != null) {
            themeIndexs.add(themeIndex);
        }
    }
    return themeIndexs;
}

@Override
public ThemeIndex getThemeIndex(Service service) {
    //SQL which is slow
    if (serviceRepository.isEpisService(service.getSvno())) {
        ...
    }

标签: javahibernatespring-bootspring-data-jpa

解决方案


您在本地调用 getServices() 因此本地方法调用没有事务代理。

您应该将计划的方法移动到其自己的组件中,并使用 getServices() 方法注入该组件。


推荐阅读