postInstantiate buildSessionFactory慢/内存庞大的数据库

拥有超过520个表的ERP数据库,EntityPersister的postInstanciate非常慢并且消耗超过512M,这对于仅一个会话Factory而言,应用程序变得非常慢。

我不能发布所有更改,但这里的想法:

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 tmp = new HashMap(); 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的加载顺序:

      

这意味着您的类应该在原始类之前加载