JPA (Hibernate) + Tomcat + две разные базы данных
У меня есть веб-приложение, использующее JPA, предоставленное Hibernate и Tomcat. У меня нет DI-фреймворка, нет Spring, нет Guice, нет полноценного сервера приложений Java EE.
Мне нужен JPA для подключения к двум разным базам данных. Я подключаюсь к первой базе данных так:
EntityManagerFactory emf = Persistence.createEntityManagerFactory("mydb");
[...]
EntityManager em = emf.createEntityManager();
и у меня есть модуль персистенции "mydb", объявленный в persistence.xml и связанный через JNDI с его ресурсом, объявленным в context.xml. До сих пор все работает.
Теперь мне нужно подключиться к другой базе данных. Я добавил его в persistence.xml и context.xml и назвал модуль персистентности "mydb2". Теперь я предполагаю, что могу использовать это так:
EntityManagerFactory emf2 = Persistence.createEntityManagerFactory("mydb2");
EntityManager em2 = emf2.createEntityManager();
Hibernate настроен для проверки классов и таблиц в обеих базах данных с
<property name="hibernate.archive.autodetection" value="class, hbm"/>
<property name="hibernate.hbm2ddl.auto" value="validate"/>
в файле persistence.xml. Однако когда я запускаю / отлаживаю веб-приложение, Hibernate пытается проверить классы @Entity, которые принадлежат mydb2 на mydb, и это, очевидно, не удается. Самое интересное, что если я установлю свойство проверки Hibernate на "none", мое приложение будет работать правильно и при необходимости подключится к нужной базе данных...
Есть ли способ заставить Hibernate проверять только те классы / таблицы, которые принадлежат их соответствующей базе данных?
РЕДАКТИРОВАТЬ: Хотя можно указать имя каталога в аннотациях @Table, в моем случае это не очень хорошее решение, потому что у меня есть несколько экземпляров этого веб-приложения в производстве, и каждый экземпляр подключается к другой паре баз данных. Быть вынужденным прикасаться к исходному коду непосредственно перед началом производства - это плохо.
1 ответ
Если вы используете аннотацию @javax.persistence.Table, вы можете использовать параметр каталога, чтобы различать базы данных.
РЕДАКТИРОВАТЬ: попробуйте определить отдельные файлы hibernate-cfg.xml (назовите их db1-hibernate-cfg.xml и db2-hibernate-cfg.xml) и в элементе xml используйте этот элемент для вывода списка объектов, соответствующих этой фабрике. Вы также можете определить их в orm.xml, который соответствует JPA.
Затем в вашей весенней конфигурации явно определите, какой hibernate-cfg (или orm.xml) сопоставляется с каким EntityManager:
Пример использования SpringContainerEntityManagerFactoryBean в Spring:
<bean id="emf" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="persistenceUnitManager" ref="pum" />
<property name="persistenceUnitName" value="my-pu" />
<property name="jpaProperties">
<props>
<prop key="hibernate.ejb.cfgfile">my-hibernate.cfg.xml</prop>
... other configurations
</props>
</bean>
Если вы идете по пути определения отдельных файлов orm.xml, то в вашем модуле управления постоянством задайте отдельный файл persistence.xml для каждой фабрики менеджера сущностей (например, db1-persistence.xml и db2..). В файле persistence.xml используйте элемент для определения соответствующего файла orm.xml.
Расположение этих файлов по умолчанию - относительный путь к классу.