拥有一个拥有520多个表的ERP数据库,EntityPersister的postInstanciate速度非常慢,并且消耗的512M以上(仅对于一个会话Factory而言是很大的),应用程序也变得非常慢。
我无法发布所有更改,但是这里有一些想法:
1_ postInstanciate为所有实体和集合创建许多Entiy加载器(每个实体和每个集合的加载器类型很多),此操作应按需执行,应在需要时创建实体或集合加载器,而不是在会话工厂构建期间,即使您有500个实体,这也意味着用户将从所有实体中加载数据。
private Map LoaderMap = new LoaderMap();//instead Hashmap class LoaderMap extends HashMap{ @Override public Object get(Object key) { Object obj = super.get(key); if (obj==null){ boolean disableForUpdate = getSubclassTableSpan() > 1 && hasSubclasses() && !getFactory().getDialect().supportsOuterJoinForUpdate(); switch (key.toString()) { case "NONE": obj = createEntityLoader( LockMode.NONE ); break; case "READ": obj = createEntityLoader( LockMode.READ ); if (disableForUpdate){ put(LockMode.UPGRADE, obj ); put(LockMode.UPGRADE_NOWAIT, obj ); put(LockMode.UPGRADE_SKIPLOCKED, obj ); put(LockMode.FORCE, obj ); put(LockMode.PESSIMISTIC_READ, obj ); put(LockMode.PESSIMISTIC_WRITE, obj ); put(LockMode.PESSIMISTIC_FORCE_INCREMENT, obj ); } break; case "UPGRADE": if (disableForUpdate) obj = get("READ"); else obj = createEntityLoader( LockMode.UPGRADE ); case "UPGRADE_NOWAIT": if (disableForUpdate) obj = get("READ"); else obj = createEntityLoader( LockMode.UPGRADE_NOWAIT ); case "UPGRADE_SKIPLOCKED": if (disableForUpdate) obj = get("READ"); else obj = createEntityLoader( LockMode.UPGRADE_SKIPLOCKED ); case "FORCE": if (disableForUpdate) obj = get("READ"); else obj = createEntityLoader( LockMode.FORCE ); case "PESSIMISTIC_READ": if (disableForUpdate) obj = get("READ"); else obj = createEntityLoader( LockMode.PESSIMISTIC_READ ); case "PESSIMISTIC_WRITE": if (disableForUpdate) obj = get("READ"); else obj = createEntityLoader( LockMode.PESSIMISTIC_WRITE ); case "PESSIMISTIC_FORCE_INCREMENT": if (disableForUpdate) obj = get("READ"); else obj = createEntityLoader( LockMode.PESSIMISTIC_FORCE_INCREMENT ); case "OPTIMISTIC": obj = createEntityLoader( LockMode.READ ); break; case "OPTIMISTIC_FORCE_INCREMENT": obj = createEntityLoader( LockMode.READ ); break; case "merge": obj = new CascadeEntityLoader( AbstractEntityPersister.this, CascadingActions.MERGE, getFactory() ); break; case "refresh": obj = new CascadeEntityLoader( AbstractEntityPersister.this, CascadingActions.REFRESH, getFactory() ); break; default: break; } put(key, obj); } return obj; } } //Relational based Persisters should be content with this implementation protected void createLoaders() { if (true) return; .... }
2_ DirectPropertyAccessor为buildGetter方法调用两次getDeclaredField,为buildSetter调用两次,使用map是一个很好的优化。
public static final Map<Double, Field> tmp = new HashMap<Double, Field>(); private static Field getField(Class root, Class clazz, String name) throws PropertyNotFoundException { if ( clazz==null || clazz==Object.class ) { throw new PropertyNotFoundException("field [" + name + "] not found on " + root.getName()); } double hash = name.hashCode() + clazz.hashCode()*1.1; Field field = tmp.get( hash ); if (field==null) try { field = clazz.getDeclaredField(name); tmp.put( hash, field ); } catch (NoSuchFieldException nsfe) { field = getField( root, clazz.getSuperclass(), name ); } field.setAccessible(true); return field; }
对Ulrich Scholz的响应 :我向项目添加了一个包含所有固定类的jar,在我的情况下,其Webapp应用程序部署在Tomcat上,您需要使用以下命令修复Jars的加载顺序:
<Context> <Resources> <PreResources className="org.apache.catalina.webresources.FileResourceSet" base="${catalina.base}/webapps/AGIWERP/WEB-INF/lib/AAACLZ-1.0.jar" webAppMount="/WEB-INF/lib/AAACLZ-1.0.jar" /> </Resources> </Context>
这意味着您的类应该在原始类之前加载