Я хочу, чтобы мой файл persistence.xml находился в папке conf моего приложения. Как я могу сообщить Persistence.createEntityManagerFactory, что он должен прочитать его оттуда?
Возможно ли иметь файл persistence.xml в другом месте, кроме META-INF?
Ответы (6)
Методы createEntityManagerFactory выполняют поиск файлов persistence.xml в каталоге META-INF любого элемента CLASSPATH. если ваш CLASSPATH содержит каталог conf, вы можете поместить определение EntityManagerFactory в conf/META-INF/persistence.xml
Если вы используете EclipseLink, вы можете указать расположение файла persistence.xml с помощью свойства модуля сохраняемости «eclipselink.persistencexml».
properties.put("eclipselink.persistencexml", "/org/acme/acme-persistence.xml");
EntityManagerFactory factory = Persistence.createEntityManagerFactory("acme", properties);
/home/foo/downloads/persistence.xml
?
- person Pavel_K; 09.10.2017
Currently, this property is used only for the canonical model generator. In the future, it may be used for customizing weaving and application bootstrapping.
- person Pavel_K; 10.10.2017
Это решение сработало для меня
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");
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);
}
};
}
Он должен работать. Работает для меня при определенных условиях тестирования и т. д. Пожалуйста, это хак и не должен использоваться в продакшене.
Мое решение предназначено для 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
. Если мы этого не сделаем, то descriptorPath по умолчанию будет равенMETA-INF/persistence.xml
, и нам нужно будет сохранить наш файл persistence.xml на/home/Smith/program/META-INF/persistence.xml
, чтобы его можно было найти.
Я пробовал эти способы при запуске программы (в первой строке основной функции):
Напишите файл persistence.xml в файле resources/META-INF/persistence.xml банки.
У меня возникла проблема с этим: Java записывает файл .txt в папку ресурсов < /а>
Создайте папку META-INF в каталоге jar и поместите в нее файл persistence.xml, затем выполните эту команду:
jar uf $jarName META-INF/persistence.xml
Эта команда заменит META-INF/persistence.xml (ваш файл) в банке.
private fun persistence() {
val fileName = "META-INF/persistence.xml"
val jarName: String?
val done = try {
jarName = javaClass.protectionDomain.codeSource.location.path
if (File(fileName).exists() && !jarName.isNullOrBlank()
&& jarName.endsWith(".jar") && File(jarName).exists()) {
Command().exec("jar uf $jarName META-INF/persistence.xml", timeoutSec = 30)
true
} else false
} catch (e: Exception) {
false
}
if (done) {
logger.info { "$fileName exist and will be loaded :)" }
} else {
logger.info {
"$fileName not exist in current folder so it will be read from .jar :(" +
" you can run: jar uf jarName.jar META-INF/persistence.xml"
}
}
}
Запуск командной строки в Java
org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean
и указав свойствоpersistenceXmlLocation
для указания на файл. - person RJo   schedule 05.12.2012