Java 安装后buildSessionFactory速度慢/内存大数据库
拥有一个包含520多个表的ERP数据库,EntityPersister的后期安装非常缓慢,其消耗量超过512M,这对于一个会话工厂来说太多了,应用程序变得非常缓慢。我无法发布所有更改,但这里的想法是: 1_uu安装后为所有实体和集合创建多个实体加载器(为每个实体和集合创建多种类型的加载器), 此操作应按需完成,实体或集合加载器应在需要时创建,而不是在会话工厂的构建过程中创建,即使您有500个实体,这意味着用户将从每个实体加载数据Java 安装后buildSessionFactory速度慢/内存大数据库,java,performance,hibernate,Java,Performance,Hibernate,拥有一个包含520多个表的ERP数据库,EntityPersister的后期安装非常缓慢,其消耗量超过512M,这对于一个会话工厂来说太多了,应用程序变得非常缓慢。我无法发布所有更改,但这里的想法是: 1_uu安装后为所有实体和集合创建多个实体加载器(为每个实体和集合创建多种类型的加载器), 此操作应按需完成,实体或集合加载器应在需要时创建,而不是在会话工厂的构建过程中创建,即使您有500个实体,这意味着用户将从每个实体加载数据 private Map LoaderMap = new L
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_uDirectPropertyAccessor调用getDeclaredField两次一次用于buildGetter方法,第二次用于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;
}
publicstaticfinalmap tmp=newhashmap();
私有静态字段getField(类根、类clazz、字符串名)引发PropertyNotFoundException{
if(clazz==null | | clazz==Object.class){
抛出新的PropertyNotFoundException(“在“+root.getName()”上找不到字段[“+name+”);
}
double hash=name.hashCode()+clazz.hashCode()*1.1;
Field=tmp.get(散列);
如果(字段==null)
试一试{
field=clazz.getDeclaredField(名称);
tmp.put(散列,字段);
}
捕获(NoSuchFieldException nsfe){
field=getField(根,clazz.getSuperclass(),名称);
}
字段。setAccessible(true);
返回字段;
}
对乌尔里希·斯科尔斯的回应:
我将一个包含所有固定类的jar添加到项目中,在我的例子中,它的Webapp应用程序部署在Tomcat上,您只需使用以下命令来固定jar的加载顺序:
<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>
这意味着您的类应该在原始类之前加载谢谢,但是一些hibernate核心修改将构建会话工厂从60秒增加到5秒(没有任何bug),但仍然要做得更好,而且内存pb不再是问题。据我所知,您可以重用SessionFactory。因此,每次启动应用程序时只需等待一次。如果您正在编写一个独立的应用程序,这可能会让人恼火,但如果您正在编写一个服务器后端,这应该不那么重要。您是否可以给出一些提示,说明如何将默认EntityPersister类替换为保存建议更改的类(安装后)。我是否需要更改hibernate代码本身,或者是否可以向库提供替换代码?我们正在使用Hibernate 3.5.2