解決Quartz定時器中查詢懶載入資料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
類省略,我們現在資料手動插入一條記錄,待會我們在定時器裡面查詢他。
定時任務程式碼如下:
/**
* Created by xujingfeng on 2016/11/3
*/
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
給定時器排程的方案用事務包裹
@Transactional
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());
}
原理就是,用事務包裹之後,會當做一個整體,沒有提交時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]
打完收工
相關推薦
解決Quartz定時器中查詢懶載入資料no session的問題
相信大家在web開發過程中一定遇到過一種情況,Class班級類一對多關聯一個Student學生類,所以為了效能考慮,配置一個lazy-init=true,然後在前臺頁面需要訪問懶載入資料時需要額外配置一個OpenSessionInViewFilter,但是可能並
Quartz定時器中Service注入時空指標問題解決
上週在做一個任務排程時,用到了Quartz定時器,用的xml配置方式,隨後進行資料庫操作時,發現service注入不進去,報空指標錯誤,然後網上查了一些資料,找到了一個比較好的解決方法,詳情如下: 1. 問題:用qu
Quartz定時器中Cron時間控制表示式寫法
Quartz定時器中Cron時間控制表示式寫法: 1、表示形式 該表示式簡潔簡單,總共有7個空格分割的表達子式,形式為【* * * * * * *】,而這七個位置上的東西表達方式有很多,意義從左往右依次是:秒 分 時 日 月 周 年,往往,“年”這個標誌位可以不寫,而
解決hibernate懶載入問題No session的問題
<!-- 解決懶載入問題 --> <filter> <filter-name>openSessionInViewFilter</filter-name> <filter-class>org.springframewo
spring quartz定時器配置-JobStoreTX方式持久化在資料庫中
配置quartz持久化在資料庫中,同樣需要以下三步配置,如下: 首先需要引入quartz所依賴的jar包 建立quartz_jobs.xml檔案用於配置排程器 引入quartz_jobs.xml 只是在為quartz定時器配置資料庫時,在quartz_jobs.xm
SSM中 Quartz(定時器)的使用
本人使用: 整合開發環境:idea 專案管理工具:maven 資料庫:oracle 框架:Spring+SpringMVC+myBatis 主要步驟: 在pom.xml中加入外掛依賴 編寫需要定時執行的方法類 編寫spring-quartz.xml配置檔案
spring整合quartz定時器的專案中,如何關閉不斷輸出的batch acquisition of 0 triggers ?
不斷輸出的batch acquisition of 0 triggers太鬧心了,嚴重影響了除錯效率,不能忍,經過查閱資料得出關閉方法。希望幫助更多的小夥伴。解決方法:在pom.xml中看看使用的是哪個
Spring的quartz定時器同一時刻重複執行二次的問題解決
最近用Spring的quartz定時器的時候,發現到時間後,任務總是重複執行兩次,在tomcat或jboss下都如此。 打印出他們的hashcode,發現是不一樣的,也就是說,在web容器啟動的時候,重複啟了兩個quartz執行緒。 研究下來發現quartz確實會載入兩次: 第一次:web容器啟動的時候,
使用python顯示影象在windows圖片檢視器中一直顯示載入中就是打不開的解決途徑
在win7下面使用PIL中Image的show()函式時,執行下列程式碼: 發現圖片在windows圖片檢視器中一直顯示載入中就是打不開 解決方法:(X為python的安裝碟符) X:\Python\lib\site-packages\PIL\ImageS
stm8l定時器中的ARPE
bit enabled 不同 err ear pre 寫入 作用 sha • Auto-reload preload enabled (ARPE bit set in the TIM1_CR1 register). In this mode,when data i
spring整合Quartz定時器
() void java類 info throws tex execute new protect 第一種:為普通java類中的某個方法配置跑批任務 1.定義要跑批的類和方法: package com.xy.utils.quartz; import org.joda.t
quartz定時器實現
quartz總結:要實現定時器quartz,我們註意兩步就行了,一是寫好實現類註意實現類的方法名要和配置中一致,二是做好配置。然後就可以測試了。①定時器實現類HealthRecodersTokenScheduler.javapublic class HealthRecodersTokenScheduler {
string整合Quartz定時器
調度 obd ont 觸發 lfa sta 每天 cron表達式 PE 直接上配置文件,此方法只需要配置好配置文件就行 1 <!--配置調度器--> 2 <bean name="startQuertz" lazy-init="false" a
springboot整合quartz定時器實現定時任務詳解
最近需要 做一個按照時間,定時初始化一些資訊的功能,研究了一下quartz,也簡單瞭解一下TimerTask,廢話不多說。 quartz和TimerTask的區別: timer是jdk自帶的(可想而知,肯定是不怎麼好用)。 Quartz可以通過cron表示式精確到特定時間執行,而T
Quartz 定時器的時間設定
時間的配置如下:<value>0 26 16 * * ?</value> 時間大小由小到大排列,從秒開始,順序為 秒,分,時,天,月,年 *為任意 ?為無限制。 由此上面所配置的內
CAD編輯器中查詢文字的功能選項在哪裡?
CAD編輯器中查詢文字的功能選項在哪裡?在編輯CAD圖紙的過程中是藉助CAD編輯器來進行繪製的,而且在圖紙中會有許多的地方需要進行標註,如果我們需要在一次查詢該文字的時候,如何使用CAD編輯器中的查詢文字功能,那CAD中查詢CAD圖紙中文字的功能選項在哪裡了?下面我們就一起來看看吧!有興趣的朋友也可以一起來看
spring-quartz 定時器 給targetMethod傳遞引數
今天在做一個專案的時候,要給一個定時器任務的執行方法傳遞引數,在網上找了一下資料,可以使用arguments引數: <bean id="subsidyJobDetail" class="org.springframework.scheduling.quartz
java定時器、Spring定時器和Quartz定時器
當前java程式中能夠實現定時的主要有三種方式,分別是:java定時器,spring定時器,quartz定時器。 下面依次講講他們的應用! java定時器的應用 其實java很早就有解決定時器任務的方法了,ja
springboot使用Quartz定時器
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-quartz</artifactId> <
quartz定時器 Job的execute使用動態引數
@GetMapping({"/addSearchIndexBySite"}) public JsonResult addSearchIndexBySite(@RequestParam(required = false) String site) throws SchedulerE