Использование нескольких модулей с независимыми экземплярами Hibernate
Я создаю многомодульный проект maven с модулями ModuleA и ModuleB ниже родительского.
Hibernate выдает MappingException
Модули используют собственное сопоставление Hibernate с собственной папкой ресурсов. Каждый модуль сохраняет свои объекты независимо от других модулей. Теперь, когда я пытаюсь создать экземпляр класса из модуля B в модуле A, я могу получить доступ ко всем необходимым методам, но когда я запускаю приложение, Hibernate выдает эту ошибку:
Exception in thread "main" org.hibernate.MappingException: Unknown entity: org.example.ModuleB.Person
at org.hibernate.internal.SessionFactoryImpl.getEntityPersister(SessionFactoryImpl.java:1096)
at org.hibernate.internal.SessionImpl.getEntityPersister(SessionImpl.java:1443)
at org.hibernate.event.internal.AbstractSaveEventListener.saveWithGeneratedId(AbstractSaveEventListener.java:116)
at org.hibernate.event.internal.DefaultSaveOrUpdateEventListener.saveWithGeneratedOrRequestedId(DefaultSaveOrUpdateEventListener.java:209)
at org.hibernate.event.internal.DefaultSaveEventListener.saveWithGeneratedOrRequestedId(DefaultSaveEventListener.java:55)
at org.hibernate.event.internal.DefaultSaveOrUpdateEventListener.entityIsTransient(DefaultSaveOrUpdateEventListener.java:194)
at org.hibernate.event.internal.DefaultSaveEventListener.performSaveOrUpdate(DefaultSaveEventListener.java:49)
at org.hibernate.event.internal.DefaultSaveOrUpdateEventListener.onSaveOrUpdate(DefaultSaveOrUpdateEventListener.java:90)
at org.hibernate.internal.SessionImpl.fireSave(SessionImpl.java:715)
at org.hibernate.internal.SessionImpl.save(SessionImpl.java:707)
at org.hibernate.internal.SessionImpl.save(SessionImpl.java:702)
Я могу добавить сопоставление для класса из ModuleB дополнительно в файл конфигурации Hibernate модуля A. Тогда это работает. Но это не так, поскольку каждый модуль должен быть независимым. Теоретически его можно хранить в совершенно другой СУБД.
Больше фона
Изначально я использовал только один модуль, он разделил его и хотел, чтобы он был более запутанным. Я выполнил mvn clean и скомпилировал все с нуля.
Кроме того, файл pom.xml из модуля A зависит от модуля B.
<dependency>
<groupId>org.example</groupId>
<artifactId>ModuleB</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
Решение
По предложению @Skizzo я просто переименовал файлы конфигурации для каждого модуля. Первоначально каждый модуль содержал файл конфигурации Hibernate с именем hibernate.cfg.xml
. Я переименовал эти файлы конфигурации в обоих модулях. Файл конфигурации ModuleA теперь называется hibernate.moduleA.cfg.xml
, а файл конфигурации ModuleB теперь называется hibernate.moduleB.cfg.xml
.
Каждый модуль также содержал класс HibernateUtil.java, используемый для инициализации фабрики сеансов. Я также переименовал классы HibernateUtil для каждого модуля. Класс Util ModuleA теперь называется HibernateUtilModuleA
, тогда как класс Util ModuleB называется HibernateUtilModuleB
. Теперь нет путаницы между двумя возможными конфигурациями, и теперь Hibernate знает, какую конфигурацию выбрать для каждого модуля.
Затем я адаптировал два класса HibernateUtil для загрузки отдельного файла конфигурации следующим образом:
HibernateUtilModuleA:
configuration.configure("hibernate.moduleA.cfg.xml");
HibernateUtilModuleB:
configuration.configure("hibernate.moduleB.cfg.xml");
Класс HibernateUtil для ModuleA теперь выглядит примерно так:
/**
* Hibernate session management
*/
public class HibernateUtilModuleA {
private static SessionFactory sessionFactory;
private static ServiceRegistry serviceRegistry;
static {
try {
Configuration configuration = new Configuration();
configuration.configure("hibernate.ModuleA.cfg.xml");
serviceRegistry = new StandardServiceRegistryBuilder().applySettings(configuration.getProperties()).build();
sessionFactory = configuration.buildSessionFactory(serviceRegistry);
} catch (HibernateException he) {
System.err.println("Error creating Session: " + he);
throw new ExceptionInInitializerError(he);
}
}
public static SessionFactory getSessionFactory() {
return sessionFactory;
}
}