Я хочу, чтобы мой файл persistence.xml в conf моего приложения. Как я могу сказать Persistence.createEntityManagerFactory, что он должен прочитать его оттуда?
Возможно ли иметь persistence.xml в другом месте, кроме META-INF?
Ответ 1
Методы createEntityManagerFactory ищут файлы persistence.xml в каталоге META-INF любого элемента CLASSPATH. если ваш CLASSPATH содержит каталог conf, вы можете поместить определение EntityManagerFactory в conf/META-INF/persistence.xml
Ответ 2
Если вы используете EclipseLink, вы можете установить местоположение persistence.xml с помощью свойства единицы сохранения, "eclipselink.persistencexml".
properties.put("eclipselink.persistencexml", "/org/acme/acme-persistence.xml");
EntityManagerFactory factory = Persistence.createEntityManagerFactory("acme", properties);
Ответ 3
Это решение сработало для меня
Thread.currentThread().setContextClassLoader(new ClassLoader() {
@Override
public Enumeration<URL> getResources(String name) throws IOException {
if (name.equals("META-INF/persistence.xml")) {
return Collections.enumeration(Arrays.asList(new File("conf/persistence.xml")
.toURI().toURL()));
}
return super.getResources(name);
}
});
Persistence.createEntityManagerFactory("test");
Ответ 4
ClassLoader может быть URLClassLoader, поэтому попробуйте его следующим образом:
final URL alternativePersistenceXmlUrl = new File("conf/persistence.xml").toURI().toURL();
ClassLoader output;
ClassLoader current = Thread.currentThread().getContextClassLoader();
try{
URLClassLoader parent = (URLClassLoader)current;
output = new URLClassLoader(parent.getURLs(), parent){
@Override
public Enumeration<URL> getResources(String name) throws IOException {
if (name.equals("META-INF/persistence.xml")) {
return Collections.enumeration(Arrays.asList(alternativePersistenceXmlUrl));
}
return super.getResources(name);
}
};
}catch(ClassCastException ignored) {
output = new ClassLoader() {
@Override
public Enumeration<URL> getResources(String name) throws IOException {
if (name.equals("META-INF/persistence.xml")) {
return Collections.enumeration(Arrays.asList(alternativePersistenceXmlUrl));
}
return super.getResources(name);
}
};
}
Он должен работать. Работает для меня при определенных условиях тестирования и т.д. Пожалуйста, это взломать и не использовать в производстве.
Ответ 5
Мое решение для EclipseLink 2.7.0 и Java 9, и это измененная и подробная версия ответа @Evgeniy Dorofeev.
В org.eclipse.persistence.internal.jpa.deployment.PersistenceUnitProcessor
на line 236
мы видим следующий код:
URL puRootUrl = computePURootURL(descUrl, descriptorPath);
Этот код используется EclipseLink для вычисления корневого url пути persistence.xml. Это очень важно, потому что окончательный путь будет сделан путем добавления descriptorPath
в puRootUrl
.
Итак, предположим, что у нас есть файл на /home/Smith/program/some-folder/persistence.xml
, тогда мы имеем:
Thread currentThread = Thread.currentThread();
ClassLoader previousClassLoader = currentThread.getContextClassLoader();
Thread.currentThread().setContextClassLoader(new ClassLoader(previousClassLoader) {
@Override
public Enumeration<URL> getResources(String name) throws IOException {
if (name.equals("some-folder/persistence.xml")) {
URL url = new File("/home/Smith/program/some-folder/persistence.xml").toURI().toURL();
return Collections.enumeration(Arrays.asList(url));
}
return super.getResources(name);
}
});
Map<String, String> properties = new HashMap<>();
properties.put("eclipselink.persistencexml", "some-folder/persistence.xml");
try {
entityManagerFactory = Persistence.createEntityManagerFactory("unit-name", properties);
} catch (Exception ex) {
logger.error("Error occured creating EMF", ex);
} finally {
currentThread.setContextClassLoader(previousClassLoader);
}
Подробнее:
- Обратите внимание, что при создании нового загрузчика классов я передаю предыдущий загрузчик классов, иначе он не работает.
- Положим свойство
eclipselink.persistencexml
. Если мы этого не сделаем, то по умолчанию дескрипторPath будет равенMETA-INF/persistence.xml
, и нам нужно будет сохранить наш persistence.xml на/home/Smith/program/META-INF/persistence.xml
.