简体   繁体   English

@Scheduled和@Transactional方法中的Spring-data-jpa延迟加载

[英]Spring-data-jpa lazy loading in @Scheduled and @Transactional methods

In my Configuration class I need to run a method as a cronjob. 在我的Configuration类中,我需要将一个方法作为cronjob运行。 So I created a method by using the @Scheduled annotation. 因此,我通过使用@Scheduled注释创建了一个方法。

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

The ThemeUpdate() method is now running in its own thread and I will lose my transaction. ThemeUpdate()方法现在正在其自己的线程中运行,我将丢失交易。 So I created another method by using the @Transactional annotation. 因此,我通过使用@Transactional注释创建了另一种方法。

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

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

    return null;
}

I get my List<Service> services from my serviceRepository . 我从serviceRepository获取List<Service> services But if I want to access a Section which is an Entity fetched by lazy loading why do I get a LazyInitializationException ? 但是,如果我想访问作为通过延迟加载获取的EntitySection ,为什么会得到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

What do I miss here? 我在这里想念什么?

EDIT: 编辑:

Scheduled: 计划:

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

getIndices(): getIndices():

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

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

getThemeIndexes(): getThemeIndexes():

@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())) {
        ...
    }

You are locally calling getServices() so there is no transaction proxy for the local method call. 您在本地调用getServices(),因此本地方法调用没有事务代理。

You should move your scheduled method in its own component and inject the component with the getServices() method. 您应该将计划的方法移到其自己的组件中,并使用getServices()方法注入该组件。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM