В моем настольном приложении новые базы данных открываются довольно часто. Я использую Hibernate
/JPA
как ORM.
Проблема в том, что создание EntityManagerFactory
происходит довольно медленно, примерно на 5-6 секунд на быстрой машине. Я знаю, что EntityManagerFactory
должен быть тяжеловесным, но это слишком медленно для настольного приложения, где пользователь ожидает, что новая база данных будет быстро открыта.
-
Можно ли отключить некоторые функции EntityManagerFactory, чтобы получить экземпляр Быстрее? Или можно лениво создать некоторую часть EntityManagerFactory, чтобы ускорить формирование?
-
Можно ли каким-либо образом создать объект EntityManagerFactory раньше зная адрес базы данных? Я был бы рад отключить все чтобы это было возможно.
-
Таким образом, могу ли я объединить EntityManagerFactorys для дальнейшего использования?
-
Любая другая идея, как быстрее создать EntityManagerFactory?
Обновление с дополнительной информацией и профилированием JProfiler
Настольное приложение может открывать сохраненные файлы. Формат файла документа приложения составляет 1 базу данных SQLite + и некоторые двоичные данные в ZIP файле. При открытии документа ZIP извлекается, а db открывается с помощью Hibernate. Все базы данных имеют одну и ту же схему, но разные данные.
Кажется, что в первый раз, когда я открываю файл, он занимает значительно больше времени, чем в следующий раз. Я профилировал первый и второй запуск с JProfiler и сравнивал результаты.
1-й прогон:
create EMF: 4385ms
build EMF: 3090ms
EJB3Configuration configure: 900ms
EJB3Configuration <clinit>: 380ms
.
2nd Run:
create EMF: 1275ms
build EMF: 970ms
EJB3Configuration configure: 305ms
EJB3Configuration <clinit>: not visible, probably 0ms
.
В сравнении дерева вызовов вы можете увидеть, что некоторые методы значительно быстрее (DatabaseManager. как отправная точка):
create EMF: -3120ms
Hibernate create EMF: -3110ms
EJB3Configuration configure: -595ms
EJB3Configuration <clinit>: -380ms
build EMF: -2120ms
buildSessionFactory: -1945ms
secondPassCompile: -425ms
buildSettings: -346ms
SessionFactoryImpl.<init>: -1040ms
Сравнение горячих точек теперь имеет интересные результаты:
.
ClassLoader.loadClass: -1686ms
XMLSchemaFactory.newSchema: -184ms
ClassFile.<init>: -109ms
Я не уверен, что это загрузка классов Hibernate или моих классов Entity.
Первым улучшением будет создание EMF, как только приложение начнет просто инициализировать все необходимые классы (у меня есть пустой файл db в качестве прототипа, уже поставляемого вместе с моим приложением). @sharakan благодарит вас за ответ, возможно, DeferredConnectionProvider уже будет решением этой проблемы.
Я попробую DeferredConnectionProvider дальше! Но мы могли бы ускорить его еще больше. У вас есть еще предложения?