I believe that everyone in the Web development process must have encountered a situation, class classes one-to-many association a student student class, so in order to consider the performance, configure a lazy-init=true, Then in the foreground page need to access lazy loading data need to configure an additional opensessioninviewfilter, but may not know what this filter does, encountered quartz timed access lazy load problem configuration This filter is useless, the following to discuss, How to solve the problem.
@Entity
@Table (name = "Clazz") public
class Clazz {
@Id
@GenericGenerator (name = "Pkuuid", strategy = " Uuid2 ")
@GeneratedValue (generator =" Pkuuid ")
@Column (length = n)
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 class omitted, we now manually insert a record of data, we will be in the timer to query him.
The timed task code is as follows:
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 ("run============================@" + New Date ());
}
}
Let's not do the additional configuration to see the results of the operation
Computer
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.examp Le.quartz.common.entity.Clazz.students, could not initialize Proxy-no Session
Can be seen, non-lazy loading data can be successfully detected, but lazy loading data will be reported no session
It is clear that the session has been closed.
Solutions 1
Off lazy loading okay well when I didn't speak
Solutions 2
A scheme for scheduling a timer with a transaction package
The principle is that after a transaction is wrapped, it will be treated as a whole, and the session will not be handed over to Sessionfactory management when not committed.
Solutions 3
Now that the session is closed, open it, like Opensessioninview, but depending on your persistence plan to decide what to open, generally sessionfactory or entitymanager, because I'm using JPA, So use the latter
Configure a task listener to open the 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 {thi
S.applicationcontext = ApplicationContext;
if (This.applicationcontext ==null) throw new RuntimeException ("ApplicationContext is null"); }
}
Then remember to register the Global Task listener with the scheduler and listen to All tasks
Dispatch Factory
@Bean public
Schedulerfactorybean Schedulerfactorybean () {
Schedulerfactorybean Factorybean = new Schedulerfactorybean ();
Factorybean.settriggers (Triggerfactorybeans (). GetObject ());
Factorybean.setglobaljoblisteners (Openentitymanagerjoblistener ());
return factorybean;
}
Try running the scheduled task again.
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) computer 131 Hibernate:select students0_.clazz_id as clazz_id 4_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:run================== ========== @Date