拥有超过520个表的ERP数据库,EntityPersister的postInstanciate非常慢,耗费超过512M,这对于一个会话工厂而言非常缓慢。
答案 0 :(得分:3)
我无法发布所有更改,但请注意以下内容:
1_ postInstanciate为所有实体和集合创建许多Entiy Loader(每个实体和每个集合的许多类型的加载器), 这个操作应该在demande上完成,实体或集合加载器应该在需要时创建,而不是在会话工厂的构建期间创建,即使你有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添加到项目中,在我的例子中,它在Tomcat上部署了Webapp应用程序,您只需要使用以下方法修复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>
这意味着您的类应该在原始类之前加载