使用jpa查数据,且使用流式处理的 parallelStream 的时候,数量在1500,核心数或许是16.
偶然出现了报错 org.hibernate.TypeMismatchException : 说预期string类型的id去做懒加载
实际传了Long类型,
于是排查源码,找到SessionImpl,有代码如下
public Object immediateLoad(String entityName, Serializable id) throws HibernateException {
if ( log.isDebugEnabled() ) {
EntityPersister persister = getFactory().getMetamodel().entityPersister( entityName );
log.debugf( "Initializing proxy: %s", MessageHelper.infoString( persister, id, getFactory() ) );
}
LoadEvent event = loadEvent;
loadEvent = null;
event = recycleEventInstance( event, id, entityName );
fireLoadNoChecks( event, LoadEventListener.IMMEDIATE_LOAD );
Object result = event.getResult();
if ( loadEvent == null ) {
event.setEntityClassName( null );
event.setEntityId( null );
event.setInstanceToLoad( null );
event.setResult( null );
loadEvent = event;
}
return result;
}
在
LoadEvent event = loadEvent; loadEvent = null;
两行,高并发下,完全可能导致event错位。
推测是别的懒加载的id,取代了当前懒加载的id。
于是设计代码,在循环懒加载时打印
1 long id = entity .getId()
2 触发entity懒加载
3 if(id != entity .getId())
Sysytem .out.print
实际真的打印出来了,说明即使没有别的懒加载类型影响,只有一种class的并发懒加载,也会有触发session内event错位的可能性。