在使用jbpm4时, 如果没用应用spring框架, 就会经常出现LazyInitializationException.<init>:42 | could not initialize proxy - no Session 这个异常, 其实, 这个主要是hibernate懒加载造成的
解决方案一般有以下方式,
1.在相应的配置文件中配置lazy="false"
2. 在需要之前,采用Hibernate.initialize()事先加载
3. 自己写拦截器处理.
对于1,这个是很好处理的, 这里就不说了.
对于3. 这个我暂时还写不好..
, 这个应该是和spring中的那个OpenSessionInViewFilter类似的.
对于2, 这里就给个简单的例子来做说明
比如说想, 通过historyActivityInstanceQuery得到HistoryTaskInstanceImpl,再由HistoryTaskInstanceImpl得到HistoryTask.
如果直接获取, 就会报LazyInitializationException异常.
可以通过以下方式获得
// 测试例子
// list
HistoryActivityInstanceQuery haiQuery = new
HistoryActivityInstanceQueryImpl().executionId(piId);
List<HistoryActivityInstance> list = processEngine.get(CommandService.class).execute(
new ListLoadImmediately<HistoryActivityInstance>((AbstractQuery) haiQuery) {
private static final long serialVersionUID = 1L;
@Override
public void doLoad(HistoryActivityInstance datum) throws HibernateException {
if (datum instanceof HistoryTaskInstanceImpl) {
Hibernate.initialize(((HistoryTaskInstanceImpl) datum).getHistoryTask()); // 预先加载了
}
}
});
for (HistoryActivityInstance hai : list) {
if (hai instanceof HistoryTaskInstanceImpl) {
HistoryTaskInstanceImpl hti = (HistoryTaskInstanceImpl) hai;
System.out.println(">> " + hti.getHistoryTask().getAssignee());
}
}
// UniqueResult
haiQuery = new HistoryActivityInstanceQueryImpl().executionId(piId).page(0, 1);
HistoryActivityInstance ai= processEngine.get(CommandService.class).execute(
new UniqueLoadImmediately<HistoryActivityInstance>
((AbstractQuery) haiQuery) {
private static final long serialVersionUID = 1L;
@Override
public void doLoad(HistoryActivityInstance datum)
throws HibernateException {
if (datum instanceof HistoryTaskInstanceImpl) {
Hibernate.initialize(
((HistoryTaskInstanceImpl) datum).getHistoryTask());// 预先加载了
}
}
});
if (ai instanceof HistoryTaskInstanceImpl) {
System.out.println(">> " + ((HistoryTaskInstanceImpl) ai).getHistoryTask()
.getAssignee());
} else {
System.out.println("not an instance of HistoryTaskInstance");
}
// 输出
// >> 王经理
// >> Sun Qi
// >> finance
// >> 张总
// >> 王经理
ListLoadImmediately.java
public abstract class ListLoadImmediately<T> implements Command<List<T>> {
private static final long serialVersionUID = 1L;
private AbstractQuery query;
public ListLoadImmediately(AbstractQuery query) {
this.query = query;
}
/* (non-Javadoc)
* @see org.jbpm.api.cmd.Command#execute(org.jbpm.api.cmd.Environment)
*/
@Override
public List<T> execute(Environment environment) throws Exception {
query.setCommandService(null); //
List<T> data = doExecute(environment);
for (T datum : data) {
doLoad(datum);
}
return data;
}
/**
* 处理要加载的数据
*
* @param datum
* @throws HibernateException
*/
public abstract void doLoad(T datum) throws HibernateException;
@SuppressWarnings("unchecked")
public List<T> doExecute(Environment environment) throws Exception {
return (List<T>) query.execute(environment);
}
}
UniqueLoadImmediately.java
/**
* @author yeyong
*/
public abstract class UniqueLoadImmediately<T> implements Command<T> {
private static final long serialVersionUID = 1L;
private AbstractQuery query;
public UniqueLoadImmediately(AbstractQuery query) {
this.query = query;
}
/* (non-Javadoc)
* @see org.jbpm.api.cmd.Command#execute(org.jbpm.api.cmd.Environment)
*/
@Override
public T execute(Environment environment) throws Exception {
query.setCommandService(null); //
T data = doExecute(environment);
doLoad(data);
return data;
}
/**
* 处理要加载的数据
*
* @param data
* @throws HibernateException
*/
public abstract void doLoad(T data) throws HibernateException;
@SuppressWarnings("unchecked")
public T doExecute(Environment environment) throws Exception {
List<T> list = (List<T>) query.execute(environment);
if (list.isEmpty()) {
return null;
}
if (list.size() > 1) {
throw new JbpmException("result not unique: " + list.size());
}
return list.get(0);
}
}