是否可以在META-INF以外的位置使用persistence.xml?
我想在我的应用程序的conf文件夹中有我的persistence.xml。 我怎么能告诉Persistence.createEntityManagerFactory它应该从那里读取它?
createEntityManagerFactory方法在任何CLASSPATH元素的META-INF目录中搜索persistence.xml文件。 如果您的CLASSPATH包含conf目录,您可以在conf / META-INF / persistence.xml中放置一个EntityManagerFactory定义
如果您使用的是EclipseLink,则可以使用持久性单元属性“eclipselink.persistencexml”设置persistence.xml位置。
properties.put("eclipselink.persistencexml", "/org/acme/acme-persistence.xml"); EntityManagerFactory factory = Persistence.createEntityManagerFactory("acme", properties);
这个解决方案对我有用
Thread.currentThread().setContextClassLoader(new ClassLoader() { @Override public Enumeration 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 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 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回答。
在line 236
org.eclipse.persistence.internal.jpa.deployment.PersistenceUnitProcessor
,我们看到以下代码:
URL puRootUrl = computePURootURL(descUrl, descriptorPath);
EclipseLink使用此代码计算persistence.xml路径的根URL。 这非常重要,因为最终路径将通过将descriptorPath
添加到puRootUrl
来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 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 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
,我们需要在/home/Smith/program/META-INF/persistence.xml
上保留我们的persistence.xml。