Как я могу сделать приложение JPA доступным к различным базам данных? - PullRequest
1 голос
/ 16 февраля 2012

Я пишу Java SE (настольное) приложение, которое должно иметь доступ к различным базам данных, каждая из которых будет иметь одинаковую модель данных (одну и ту же схему, таблицы и т. Д.).Я хочу повторно использовать объекты JPA, которые я уже использую, в приложении Java EE, стоящем перед каждой базой данных.

Чтобы повторно использовать существующий файл entity.jar, мне нужно будет упаковать его в другой файл persistence.xml с источником данных resource_local.Это неудобство во время сборки, но не большая проблема.

Проблема в том, что мое настольное приложение будет ограничено использованием источника данных, определенного в файле persistence.xml.Я мог бы определить несколько единиц персистентности и выбрать, какие из них использовать во время выполнения, но когда добавится новая база данных, мне придется изменить файл persistence.xml и обновить все двоичные файлы рабочего стола.

Я бы хотелуметь определять новые источники данных в файле .properties, который может настраивать каждый пользователь.Есть ли способ переопределить или добавить единицы постоянства, объявленные в файле persistence.xml во время выполнения?

Я не хочу создавать приложения Java EE с интерфейсами веб-служб только для поддержки этого настольного приложения.Приложения Java EE имеют другое назначение, и я хочу сохранить функциональность рабочего стола в приложении для настольных компьютеров.

Спасибо.

Ответы [ 2 ]

6 голосов
/ 18 февраля 2012

Вы можете создать EntityManagerFactory во время выполнения, указав свойства.

Map<String, Object> properties = new HashMap<String, Object>();

properties.put(TRANSACTION_TYPE, PersistenceUnitTransactionType.RESOURCE_LOCAL.name());
properties.put(JDBC_DRIVER, driver);
properties.put(JDBC_URL, db_url);
properties.put(JDBC_USER, "userName");
properties.put(JDBC_PASSWORD, "password");

EntityManagerFactory factory = Persistence.createEntityManagerFactory("PERSISTENT_UNIT_NAME", properties);

Также вы можете попробовать создать файл свойств, из которого свойства будут загружены во время выполнения в карту.Поэтому он будет отделять конфигурацию базы данных от кода.

Редактировать: Ключи свойств (JDBC_URL и т. Д.) Зависят от поставщика, их следует соответствующим образом заменить.

3 голосов
/ 22 февраля 2012

Nayan,

Мне нужно расширить ваш ответ, потому что он не завершен.

Запутанная вещь об использовании свойств для динамического создания EntityManager состоит в том, что в JPA есть три метода createEntityManagerFactory (), и все 3 имеют имя единицы постоянства. Я не осознавал, что свойства переопределяют имя модуля постоянства, пока не проверил спецификацию JPA 2.0. В разделе 9.4.3 говорится, что свойства переопределяют значения, указанные в файле persistence.xml. Он также показывает, что представляют собой стандартные имена свойств.

(JavaDocs не говорит вам, что может входить в свойства, и они не говорят, что свойства переопределяют то, что находится в persistence.xml. Другой пример, где JavaDocs отстой.)

В вашем примере используются имена свойств, такие как "JDBC_URL", которых нет в Javadocs API Java EE 6. В спецификации JPA поясняется, что в дополнение к стандартным свойствам могут использоваться специфические для поставщика имена свойств. Документы EclipseLink показывают, какие имена свойств поддерживает реализация через нестандартный класс PersistenceUnitProperties:

http://www.eclipse.org/eclipselink/api/2.3/index.html

Таким образом, чтобы иметь динамические EntityManager, необходимо использовать специфичные для поставщика свойства, чтобы динамические менеджеры объектов не были переносимы. Я думаю, у тебя не может быть всего.

Один из случаев, когда динамические EntityManager были бы переносимыми, - это использование стандартного свойства javax.persistence.jtaDataSource. Вам придется добавить источник данных в ваш контейнер Java EE, но это настолько динамично, насколько это возможно при работе в контейнере. В Java SE это не похоже на какие-либо переносимые, динамические опции.

JavaDocs должен гораздо лучше объяснить, как свойства работают с методами createEntityManagerFactory ().

...