META-INF/persistence.xml 无法打开,因为它不存在
Posted
技术标签:
【中文标题】META-INF/persistence.xml 无法打开,因为它不存在【英文标题】:META-INF/persistence.xml cannot be opened because it does not exist 【发布时间】:2012-08-30 07:27:57 【问题描述】:我正在创建一个基本的 spring-maven 项目,该项目应该作为 java 应用程序运行(在进程中,而不是通过 Web 服务器)。
我的应用程序上下文位于我的类路径中的资源文件夹下:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p"
xmlns:aop="http://www.springframework.org/schema/aop" xmlns:context="http://www.springframework.org/schema/context"
xmlns:tx="http://www.springframework.org/schema/tx" xmlns:ox="http://www.springframework.org/schema/oxm"
xsi:schemaLocation="
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.1.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.1.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.1.xsd
http://www.springframework.org/schema/oxm http://www.springframework.org/schema/oxm/spring-oxm-3.1xsd">
<!-- Root Context: defines shared resources visible to all other web components -->
<!-- Context -->
<context:component-scan base-package="me.co.nutrition" />
<!-- Properties -->
<context:property-placeholder
location="classpath:/nutrition.accumulation.properties" />
<!-- DB -->
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource">
<property name="driverClassName" value="$jdbc.driverClassName" />
<property name="url" value="$jdbc.url" />
<property name="username" value="$jdbc.username" />
<property name="password" value="$jdbc.password" />
</bean>
<bean id="persistenceUnitManager"
class="org.springframework.orm.jpa.persistenceunit.DefaultPersistenceUnitManager">
<property name="defaultPersistenceUnitName" value="nutrition-pu"/>
<property name="persistenceXmlLocation" value="classpath:META-INF/persistence.xml"/>
<property name="defaultDataSource" ref="dataSource" />
</bean>
<!-- JPA -->
<bean id="entityManager"
class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="dataSource" ref="dataSource" />
<property name="persistenceUnitManager" ref="persistenceUnitManager" />
<property name="jpaVendorAdapter" ref="jpaVendorAdapter" />
</bean>
<!-- jpaVendorAdapter (works in conjunction with the persistence.xml) -->
<bean id="jpaVendorAdapter"
class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
<property name="database" value="$jpa.database" />
<property name="showSql" value="$jpa.showSql" />
<property name="databasePlatform" value="$jpa.dialect" />
<property name="generateDdl" value="$jpa.generateDdl" />
</bean>
<!-- Transactions -->
<tx:annotation-driven transaction-manager="transactionManager" />
<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
<property name="entityManagerFactory" ref="entityManager" />
<property name="dataSource" ref="dataSource" />
</bean>
<bean id="persistenceAnnotation" class="org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor" />
</beans>
我创建了一个 META-INF 文件夹作为源文件夹,并将这个文件夹添加到我的类路径中。我在这个文件夹下创建了我的 persistence.xml 文件。
这是我的 persistence.xml:
<?xml version="1.0" encoding="UTF-8"?>
<persistence xmlns="http://java.sun.com/xml/ns/persistence"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd"
version="2.0">
<persistence-unit name="nutrition-pu" transaction-type="RESOURCE_LOCAL">
<provider>org.hibernate.ejb.HibernatePersistence</provider>
</persistence-unit>
</persistence>
如前所述,它位于我的类路径中的 META-INF 文件夹下。这是我的 .classpath 文件:
<?xml version="1.0" encoding="UTF-8"?>
<classpath>
<classpathentry kind="src" output="target/classes" path="src/main/java"/>
<classpathentry kind="src" output="target/test-classes" path="src/test/java"/>
<classpathentry kind="src" path="META-INF"/>
<classpathentry kind="src" path="resources"/>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.6"/>
<classpathentry kind="con" path="org.eclipse.m2e.MAVEN2_CLASSPATH_CONTAINER"/>
<classpathentry kind="output" path="target/classes"/>
</classpath>
您可以看到 META-INF 文件夹在那里。 我创建了一个简单的 main 运行:
public static void main(String[] args) throws Exception
ApplicationContext context = new ClassPathXmlApplicationContext("accumulationApplicationContext.xml");
...
当我运行它时,当我尝试加载应用程序上下文时,我得到一个异常,提示无法找到或解析persistence.xml:
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'persistenceUnitManager' defined in class path resource [accumulationApplicationContext.xml]: Invocation of init method failed; nested exception is java.lang.IllegalArgumentException: Cannot parse persistence unit from class path resource [META-INF/persistence.xml]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1455)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:519)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:456)
at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:294)
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:225)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:291)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:193)
at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveReference(BeanDefinitionValueResolver.java:322)
... 30 more
Caused by: java.lang.IllegalArgumentException: Cannot parse persistence unit from class path resource [META-INF/persistence.xml]
at org.springframework.orm.jpa.persistenceunit.PersistenceUnitReader.readPersistenceUnitInfos(PersistenceUnitReader.java:141)
at org.springframework.orm.jpa.persistenceunit.DefaultPersistenceUnitManager.readPersistenceUnitInfos(DefaultPersistenceUnitManager.java:380)
at org.springframework.orm.jpa.persistenceunit.DefaultPersistenceUnitManager.preparePersistenceUnitInfos(DefaultPersistenceUnitManager.java:341)
at org.springframework.orm.jpa.persistenceunit.DefaultPersistenceUnitManager.afterPropertiesSet(DefaultPersistenceUnitManager.java:326)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1514)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1452)
... 37 more
Caused by: java.io.FileNotFoundException: class path resource [META-INF/persistence.xml] cannot be opened because it does not exist
at org.springframework.core.io.ClassPathResource.getInputStream(ClassPathResource.java:158)
at org.springframework.orm.jpa.persistenceunit.PersistenceUnitReader.readPersistenceUnitInfos(PersistenceUnitReader.java:129)
我无法理解这个问题。我很确定我有right 结构,为什么我的persistence.xml 无法加载?
提前致谢!
更新:
感谢Boris 我得到了它的工作。似乎我在错误的路径下创建了 META-INF。发生这种情况是因为我错过了对 Eclipse 项目结构的理解。 This 是正确的结构。我希望这对某人有所帮助..
【问题讨论】:
【参考方案1】:您的 META-INF 文件夹应该直接在源文件夹下,而不是本身就是源文件夹。
见Where do I put META-INF in Eclipse?
更新From JPA 2.0 Specification
8.2 <...> 持久性单元由persistence.xml 文件定义。 jar 文件或目录 META-INF 目录包含persistence.xml 文件,称为持久单元的根。 在 Java EE 环境中,持久单元的根必须是以下之一:
一个 EJB-JAR 文件 WAR 文件的 WEB-INF/classes 目录 WAR文件的WEB-INF/lib目录下的jar文件 EAR库目录下的jar文件 应用程序客户端 jar 文件
8.2.1 <...> persistence.xml 文件定义了一个持久性单元。 persistence.xml 文件位于 META-INF 持久化单元根目录。
因此,您如何配置项目并没有什么区别,重要的是生成的 jar。如果您使用的是 maven,通常的做法是使用 src/main/resources 文件夹作为 META-INF。
【讨论】:
Thakns。我通过右键单击我的 src/main/java 文件夹创建了 META-INF,创建了一个名为 META-INF 的新源文件夹。通过这样做,新文件夹被创建为我的类路径中的源文件夹。据我了解,重要的是,无论在哪个层次结构下,它都将不符合我的类路径(这不是 classpathXmlApplicationContext 的目的吗?)。无论如何,事实上我应该怎么做才能使它正确? Classpathxmlapplicationcontext 的目的是从类路径加载 xml 配置,而不是像 FileSystemXmlApplicationContext 那样从文件系统加载。无需将 Spring 配置文件放入 META-INF,它将从类路径中的任何位置获取。附:不要将 spring bean 配置与由 JPA 标准规定的位置的 persistence.xml 混淆。 嗨,鲍里斯,我确实把它弄混了,谢谢。无论如何,我的应用程序上下文位于我以与创建 META-INF 文件夹相同的方式创建的资源文件夹下。 Classpathxmlapplicationcontext gest 从资源文件夹加载得很好,但persistence.xml 无法从 META-INF 文件夹加载,这是问题所在。我想知道我是否应该为此目的找到更合适的 maven Archetype。我使用了不创建 META-INF 文件夹的 Quick Start Archetype。你知道我的目的更好的原型吗?这可能是问题吗? 这不是一个网络应用程序,这里没有涉及应用程序服务器,所以与 JEE 相关的答案并不完全适合(我没有战争文件..)。我红了文档,我需要一个我似乎仍然找不到的明确答案。为了用 Eclipse 重新定位我的 META-INF 文件夹,我应该怎么做?如您所见,它目前在我的类路径中,我还应该把它放在哪里? @YogevLidor 请改写 - META-INF 是JAR file specification 的一部分,您无法将其重新定位到 jar 文件中。基本上源文件中的所有内容都将被复制到生成的 jar 中,因此sourcefolder/META-INF/something*
的内容将降落到jarfile.jar/META-INF/something*
当 java 应用程序启动时,通常您的 jar 文件将被指定为类路径 java -classpath jarfile.jar MainClass
最后Spring 将使用类加载器选择资源。以上是关于META-INF/persistence.xml 无法打开,因为它不存在的主要内容,如果未能解决你的问题,请参考以下文章
java.sql.SQLException: ORA-02289: 序列不存在