1. 程式人生 > >spring 任務排程中出現懶載入 no session 問題

spring 任務排程中出現懶載入 no session 問題

相信大家在web開發過程中一定遇到過一種情況,Class班級類一對多關聯一個Student學生類,所以為了效能考慮,配置一個lazy-init=true,然後在前臺頁面需要訪問懶載入資料時需要額外配置一個OpenSessionInViewFilter,但是可能並不知道這個過濾器到底做了什麼,遇到Quartz定時中訪問懶載入問題配置這個filter可沒有用了,下面來討論下,怎麼解決這個問題。

@Entity
@Table(name = "clazz")
public class Clazz {
    @Id
    @GenericGenerator(name = "PKUUID", strategy = "uuid2"
) @GeneratedValue(generator = "PKUUID") @Column(length = 36) private String id; private String clazzName; private String clazzNumber; @OneToMany(fetch = FetchType.LAZY,mappedBy = "clazz",cascade = CascadeType.ALL) private List<Student> students; get/set... }

Student類省略,我們現在資料手動插入一條記錄,待會我們在定時器裡面查詢他。

定時任務程式碼如下:


public class DemoJob {

    @Autowired
    ClazzDao clazzDao;

    public static final Logger logger = LoggerFactory.getLogger(DemoJob.class);

    public DemoJob() {
        System.out.println("DemoJob=====>init");
    }

    public void run() {

        Clazz clazz = clazzDao.findOne("ba9071fb-f2da-481a-9a90-371022cda195"
); System.out.println(clazz.getClazzName()); System.out.println(clazz.getClazzNumber()); System.out.println(clazz.getStudents()); logger.info("[email protected]" + new Date()); } }

我們先不做額外配置看看執行結果

計算機
131
2016-11-04 10:16:50.213 ERROR 6692 --- [ryBean_Worker-1] org.quartz.core.JobRunShell              : Job job_work.job_name threw an unhandled Exception: 

org.springframework.scheduling.quartz.JobMethodInvocationFailedException: Invocation of method 'run' on target class [class com.example.quartz.job.DemoJob] failed; nested exception is org.hibernate.LazyInitializationException: failed to lazily initialize a collection of role: com.example.quartz.common.entity.Clazz.students, could not initialize proxy - no Session

可以看到,非懶載入資料可以順利查出來,但是懶載入資料會報no session

很明顯,session已經關閉了。

解決方案1
關閉懶載入,好吧,當我沒講
解決方案2
給定時器排程的方案用事務包裹
原理就是,用事務包裹之後,會當做一個整體,沒有提交時session不會交給SessionFactory管理

解決方案3
既然session關閉了,那就開啟它就行了,類似於OpensessionInView,不過要取決於你的持久化方案來決定到底開啟什麼,一般是SessionFactory或者EntityManager,由於我是採用的JPA,所以使用後者

配置一個任務監聽器,用於開啟session

public class OpenEntityManagerJobListener extends JobListenerSupport implements ApplicationContextAware {

    @Override
    public String getName() {
        return "OpenEntityManagerJobListener";
    }

    EntityManagerFactory entityManagerFactory;

    @Override
    public void jobToBeExecuted(JobExecutionContext context) {
        entityManagerFactory = applicationContext.getBean(EntityManagerFactory.class);
        EntityManager entityManager = entityManagerFactory.createEntityManager();
        EntityManagerHolder emHolder = new EntityManagerHolder(entityManager);
        TransactionSynchronizationManager.bindResource(entityManagerFactory, emHolder);
    }

    @Override
    public void jobWasExecuted(JobExecutionContext context, JobExecutionException jobException) {
        EntityManagerHolder emHolder = (EntityManagerHolder) TransactionSynchronizationManager.unbindResource(entityManagerFactory);
        EntityManagerFactoryUtils.closeEntityManager(emHolder.getEntityManager());
    }


    ApplicationContext applicationContext;

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        this.applicationContext = applicationContext;
        if(this.applicationContext ==null) throw new RuntimeException("applicationContext is null");
    }
}

之後記得給排程器註冊全域性任務監聽器,對所有任務監聽

//排程工廠
    @Bean
    public SchedulerFactoryBean schedulerFactoryBean() {
        SchedulerFactoryBean factoryBean = new SchedulerFactoryBean();
        factoryBean.setTriggers(triggerFactoryBeans().getObject());
        factoryBean.setGlobalJobListeners(openEntityManagerJobListener());
        return factoryBean;
    }

再來試試執行一下定時任務

2016-11-04 10:29:12.234  INFO 11188 --- [           main] com.example.quartz.CommonApp             : Started CommonApp in 12.067 seconds (JVM running for 12.675)
計算機
131
Hibernate: select students0_.clazz_id as clazz_id4_1_0_, students0_.id as id1_1_0_, students0_.id as id1_1_1_, students0_.clazz_id as clazz_id4_1_1_, students0_.stu_name as stu_name2_1_1_, students0_.stu_numer as stu_numer3_1_1_ from student students0_ where students0_.clazz_id=?
[com.example.quartz.common.entity.Student@2cd010f8, com.example.quartz.common.entity.Student@100a20c4]
2016-11-04 10:29:12.336  INFO 11188 --- [ryBean_Worker-1] com.example.quartz.job.DemoJob           : [email protected]

相關推薦

spring 任務排程出現載入 no session 問題

相信大家在web開發過程中一定遇到過一種情況,Class班級類一對多關聯一個Student學生類,所以為了效能考慮,配置一個lazy-init=true,然後在前臺頁面需要訪問懶載入資料時需要額外配置一個OpenSessionInViewFilter,但是可能並

解決spring+springMVC+Hibernate+spring-data-jpa載入No session問題

在使用懶載入的時候常常會遇到No session問題,其實是在web.xml檔案中忘記新增懶載入的過濾器了。 懶載入異常:org.hibernate.LazyInitializationException: could not initialize proxy

解決Quartz定時器查詢載入資料no session的問題

相信大家在web開發過程中一定遇到過一種情況,Class班級類一對多關聯一個Student學生類,所以為了效能考慮,配置一個lazy-init=true,然後在前臺頁面需要訪問懶載入資料時需要額外配置一個OpenSessionInViewFilter,但是可能並

在Pycharm出現“pip has no attribute 'main'”問題的解決

在使用Pycharm中的setting來安裝包的時候,出現如標題的報錯。我就有點納悶了,上網找解決方案,能夠這樣解決 1.首先,這個是Pycharm的問題,在Pycharm的安裝目錄下面的helpers資料夾下找到packaging_tool.py,並開啟 然後,找到下面的程式碼段:

Spring任務排程實戰之Quartz Simple Trigger

分享一下我老師大神的人工智慧教程!零基礎,通俗易懂!http://blog.csdn.net/jiangjunshow 也歡迎大家轉載本篇文章。分享知識,造福人民,實現我們中華民族偉大復興!        

vue專案實現載入

Vue-lazyload外掛實現懶載入 一. 外掛的下載: 利用npm下載安裝到專案中 npm install vue-lazyload --save-dev 二.外掛的註冊,及屬性的配置。 接下來只需要,在專案的入口檔案 main.js 中進行相關的屬性配置和註冊即可。

spring註解@lazy,bean載入

當使用@Scope註解的singleton屬性時,bean的例項會在IOC容器建立的時候被載入,但是如果在建立bean的時候加上@lazy註解,則bean的例項會在第一次使用的時候被建立。 @Lazy @Scope(value = ConfigurableB

解決Spring Data JPA延遲載入no session錯誤

專案採用spring boot構建,提供restful介面給PHP呼叫,介面類統一使用@RestController註解實體關係 @ManyToOne(fetch = FetchType.LAZY) @JoinColumn(name = "department_id")

uC/OS-II任務排程判斷最高優先順序

一、任務優先順序的表示    uC/OS-II中,規定最多可以有64個任務。每個任務的優先順序不能相同,因此,優先順序為0~63.數字越小,優先順序越高,那麼0就是最高優先順序,63就是最低優先順序。系統保留了優先順序最高及最低的各4個,因此使用者不能使用這8個優先順序作為自己的任務的優先順序。巨集OS_L

Spring整合Shiro出現There is no session with id [XXX] with root cause問題的解決方案

最近使用spring + shiro整合的時候出現一個非常頭疼的問題,就是會經常出現There is no session with id [XXX]的問題,而且非常難調試出問題的所在,原始碼也看了關於shiro的部分,但是原因還是找不到。廢話不多說,直接上配置檔案shiro

Hibernate載入

考慮一個簡單的網路應用程式:網上書店,書店維護者產品的目錄。最原始的方法,它可以投射到一個模型實體中去用來管理一系列的產品實體。在一個大的書店中,會有成千上萬的產品劃分成不同的目錄。當一個使用者訪問這個書店的時候,目錄必須要從資料庫中載入,我們很可能不想要載入每一個實體到記憶體中去。對於一個大型的零售商,考慮

關於Spring 任務排程之task:scheduler與task:executor配置的詳解

其實就是Spring定時器中配置檔案中一些配置資訊,由於筆者自己是頭一次使用,有些配置詳細不太明白,隨即研究了一番,於是想記錄一下,有需要的小夥伴可以參考,也方便日後自己查閱。首先,建立一個僅僅包含定時器配置的Spring配置檔案:spring-timer.xml。以下均為配

Vue載入和按需載入

{test: /iview.src.*?js$/</span>, <span class="hljs-attr">loader</span>: <span class="hljs-string">'babel'</span> },&l

Eclipse出現there is no staged files

1、 preferences->git->committing 將use stage view to commit instead of commit dialog 的勾去

js載入函式

測試程式碼1: function createXHR() { if(typeof XMLHttpRequest!='undfined') { return new XMLHttpRe

定時任務 quartz出現相同型別的物件無法轉換問題(java.lang.ClassCastException)

環境:springboot 排查問題過程: 1:確認不是serialVersionUID版本問題 2:確認不是序列化工具(Jackson)問題 3:寫了一個測試方法:將物件put到JobDataMap中,再取出來強轉,並無問題 解決方法:去掉spring-boot-

spring+springmvc+myibatic出現了Error creating bean with name 'userService':

我在搭建spring+springmvc+myibatic中出現了 org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'userService': I

iOS載入

iOS開發中 我們經常使用懶載入 1.懶載入的好處,讓控制元件和物件在最需要載入的時候載入。這樣可以節省記憶體空間,因為我們移動的裝置資源還是比較寶貴的。所謂懶載入 就是推遲他的getter方法的執行。 比如。一個view的子控制元件 ,只有當這個view被顯示的時候才去載

spring boot項目啟動報(No session repository could be auto-configured, check your configuration (session store type is 'null'))

ssi 問題解決 conf 重新啟動 null 增加 boot 修改 ati 找到項目的application配置文件,增加 spring.session.store-type=none,重新啟動問題解決 註:因為項目未使用redis管理session,可以如上設置,如果想

hibernate載入導致session關閉後無法在view層得到關聯資料

在controller中查詢出了一個數據,資料關聯了另外一個物件,在頁面中用A.GETB().GETXXX()的方式的時候就會報錯,因為是懶載入,預設的session已經關閉了。 解決方案:在web.xml配置檔案中加入以下內容 <filter> <fi