我已经搜索了整个 SO,虽然存在具有相似标题的帖子,但这是一个不同的场景。
我的 Eclipse 中有两个项目 1) 一个 JPA 项目 2) 一个使用 JPA 项目中的实体的 Web 项目。两者都启用了 OSGi 和 Maven。我正在使用最新的 SpringFramework (3.1.1) 在 Web 项目中创建 RESTful Web 服务。
项目布局如下:
1) JPA 项目
com.demo.persistence
|-src
|-com.demo.persistence
|-User
|-META-INF
|-MANIFEST.MF
|-persistence.xml
|-pom.xml
2) 网络项目
com.demo.web
|-src
|-com.demo.web.controller
|-Controller.java
|-com.demo.web.dao
|-UserDAO.java
|-UserListDAO.java
|-com.demo.web.model
|-UserBean.java
|-com.demo.web.interfaces
|-UserDAOIntf.java
|-WebContent
|-META-INF
|-MANIFEST.MF
|-WEB-INF
|-classes
|-log4j.properties
|-rest-context.xml
|-rest-context-osgi.xml
|-rest-servlet.xml
|-web.xml
|-pom.xml
com.demo.persistence.User.java
@Entity
@XmlRootElement(name="user")
@Table(name = "T_USER")
@NamedQuery(name = "AllUsers", query = "select u from User u")
public class User {
@Id
@GeneratedValue
@Column(nullable = false)
private long id;
@Basic
@Column(nullable = false)
private String userName;
public void setUserName(String param) {
this.userName = param;
}
public String getUserName() {
return userName;
}
}
com.demo.web.dao.UserDAO
public class UserDAO implements UserDAOInterface {
@PersistenceContext
private EntityManager em;
public User getUser(Long id) {
try{
return em.find(User.class, id);
} finally {
if(em != null)
em.close();
}
}
public List<User> getAllUsers() {
try {
List<User> users = em.createNamedQuery("AllUsers", User.class).getResultList();
return users;
} finally {
if(em != null)
em.close();
}
}
@Transactional
public User addUser(User user) {
try {
em.persist(user);
em.flush();
return user;
} finally {
if(em != null)
em.close();
}
}
}
com.demo.web.model
public class UserBean {
private UserDAO userDAO;
public void addUserDetails( String userName ) {
User user = new User();
user.setUserName(userName);
this.userDAO.addUser(user);
}
public List<User> getAllUsers() {
return this.userDAO.getAllUsers();
}
public User getUser(Long id) {
return this.userDAO.getUser(id);
}
public User addUser(User user) {
return this.userDAO.addUser(user);
}
}
com.demo.web.controller.Controller
@Controller
public class Controller {
private Jaxb2Marshaller jaxb2Marshaller;
private UserBean userBean;
public Jaxb2Marshaller getJaxb2Mashaller() {
return jaxb2Marshaller;
}
public void setJaxb2Mashaller(Jaxb2Marshaller jaxb2Marshaller) {
this.jaxb2Marshaller = jaxb2Marshaller;
}
@RequestMapping(method=RequestMethod.GET, value="/rest/users", headers="Accept=application/xml, application/json")
public @ResponseBody UserListDAO getUserList() {
return new UserListDAO(userBean.getAllUsers());
}
@RequestMapping(method=RequestMethod.GET, value="rest/user/{id}", headers="Accept=application/xml, application/json")
public @ResponseBody User getUser(@PathVariable Long id) {
return userBean.getUser(id);
}
@RequestMapping(method=RequestMethod.POST, value="rest/user/add", headers="Accept=application/xml, application/json")
public @ResponseBody User addUser(@RequestBody String userString) {
Source source = new StreamSource(new StringReader(userString));
User user = (User) jaxb2Marshaller.unmarshal(source);
return userBean.addUser(user);
}
web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
xsi:schemaLocation=
"http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
id="WebApp_ID" version="2.5">
<display-name>com.demo.web</display-name>
<welcome-file-list>
<welcome-file>index.html</welcome-file>
</welcome-file-list>
<context-param>
<param-name>log4jConfigLocation</param-name>
<param-value>
/WEB-INF/classes/log4j.properties
</param-value>
</context-param>
<listener>
<listener-class>
org.springframework.web.util.Log4jConfigListener
</listener-class>
</listener>
<!-- The context params that read by ContextLoaderListener -->
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>
/WEB-INF/rest-context.xml
</param-value>
</context-param>
<!-- This listener will load other application context file in addition to springweb-servlet.xml -->
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<servlet>
<servlet-name>rest</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>rest</servlet-name>
<url-pattern>/service/*</url-pattern>
</servlet-mapping>
</web-app>
休息上下文.xml
<?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:tx="http://www.springframework.org/schema/tx"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-2.0.xsd">
<context:annotation-config />
<context:component-scan base-package="com.demo.web.controller" />
<tx:annotation-driven transaction-manager="transactionManager" />
<bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalEntityManagerFactoryBean">
<property name="persistenceUnitName" value="com.demo.persistence" />
</bean>
<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
<property name="entityManagerFactory" ref="entityManagerFactory" />
</bean>
<!-- Bean - DAO Mapping -->
<bean id="userDAO" class="com.demo.dao.UserDAO">
<property name="entityManagerFactory" ref="entityManagerFactory" />
</bean>
<!-- Bean Declarations -->
<bean id="userBean" class="com.demo.web.model.UserBean">
<property name="userDAO" ref="userDAO" />
</bean>
</beans>
休息上下文osgi.xml
<?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:osgi="http://www.springframework.org/schema/osgi"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/osgi
http://www.springframework.org/schema/osgi/spring-osgi-1.0.xsd">
<osgi:service interface="javax.persistence.EntityManager" ref="entityManagerFactory" />
</beans>
休息-servlet.xml
<?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:mvc="http://www.springframework.org/schema/mvc"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd">
<!-- To enable @RequestMapping process on type level and method level -->
<bean class="org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping" />
<bean class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter">
<property name="messageConverters">
<list>
<ref bean="marshallingConverter" />
<ref bean="jsonConverter" />
</list>
</property>
</bean>
<bean id="marshallingConverter" class="org.springframework.http.converter.xml.MarshallingHttpMessageConverter">
<constructor-arg ref="jaxbMarshaller" />
<property name="supportedMediaTypes" value="application/xml"/>
</bean>
<bean id="jsonConverter" class="org.springframework.http.converter.json.MappingJacksonHttpMessageConverter">
<property name="supportedMediaTypes" value="application/json" />
</bean>
<bean id="jaxbMarshaller" class="org.springframework.oxm.jaxb.Jaxb2Marshaller">
<property name="classesToBeBound">
<list>
<value>com.demo.persistence.User</value>
<value>com.demo.dao.UserListDAO</value>
</list>
</property>
</bean>
<bean id="users" class="org.springframework.web.servlet.view.xml.MarshallingView">
<constructor-arg ref="jaxbMarshaller" />
</bean>
<!--bean id="viewResolver" class="org.springframework.web.servlet.view.BeanNameViewResolver" /-->
<bean id="userController" class="com.demo.web.controller.Controller">
<property name="userDAO" ref="userDAO" />
<property name="jaxb2Mashaller" ref="jaxbMarshaller" />
</bean>
</beans>
控制台 - log4j
ERROR [org.springframework.web.context.ContextLoader] - Context initialization failed
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'entityManagerFactory' defined in ServletContext resource [/WEB-INF/rest-context.xml]: Invocation of init method failed; nested exception is javax.persistence.PersistenceException: No Persistence provider for EntityManager named com.demo.persistence
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.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:567)
at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:913)
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:464)
at org.springframework.web.context.ContextLoader.configureAndRefreshWebApplicationContext(ContextLoader.java:385)
at org.springframework.web.context.ContextLoader.initWebApplicationContext(ContextLoader.java:284)
at org.springframework.web.context.ContextLoaderListener.contextInitialized(ContextLoaderListener.java:111)
at org.apache.catalina.core.StandardContext.listenerStart(StandardContext.java:4779)
at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5273)
at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:150)
at org.apache.catalina.core.ContainerBase.addChildInternal(ContainerBase.java:897)
at org.apache.catalina.core.ContainerBase.access$000(ContainerBase.java:131)
at org.apache.catalina.core.ContainerBase$PrivilegedAddChild.run(ContainerBase.java:154)
at org.apache.catalina.core.ContainerBase$PrivilegedAddChild.run(ContainerBase.java:143)
at java.security.AccessController.doPrivileged(Native Method)
at org.apache.catalina.core.ContainerBase.addChild(ContainerBase.java:871)
at org.apache.catalina.core.StandardHost.addChild(StandardHost.java:615)
at org.eclipse.gemini.web.tomcat.internal.TomcatServletContainer.startWebApplication(TomcatServletContainer.java:122)
at org.eclipse.gemini.web.internal.StandardWebApplication.start(StandardWebApplication.java:91)
at org.eclipse.gemini.web.extender.WebContainerBundleCustomizer.addingBundle(WebContainerBundleCustomizer.java:45)
at org.osgi.util.tracker.BundleTracker$Tracked.customizerAdding(BundleTracker.java:482)
at org.osgi.util.tracker.BundleTracker$Tracked.customizerAdding(BundleTracker.java:1)
at org.osgi.util.tracker.AbstractTracked.trackAdding(AbstractTracked.java:262)
at org.osgi.util.tracker.AbstractTracked.track(AbstractTracked.java:234)
at org.osgi.util.tracker.BundleTracker$Tracked.bundleChanged(BundleTracker.java:457)
at org.eclipse.osgi.framework.internal.core.BundleContextImpl.dispatchEvent(BundleContextImpl.java:847)
at org.eclipse.osgi.framework.eventmgr.EventManager.dispatchEvent(EventManager.java:230)
at org.eclipse.osgi.framework.eventmgr.ListenerQueue.dispatchEventSynchronous(ListenerQueue.java:148)
at org.eclipse.osgi.framework.internal.core.Framework.publishBundleEventPrivileged(Framework.java:1522)
at org.eclipse.osgi.framework.internal.core.Framework$7.run(Framework.java:1462)
at java.security.AccessController.doPrivileged(Native Method)
at org.eclipse.osgi.framework.internal.core.Framework.publishBundleEvent(Framework.java:1460)
at org.eclipse.osgi.framework.internal.core.Framework.publishBundleEvent(Framework.java:1453)
at org.eclipse.osgi.framework.internal.core.BundleHost.startWorker(BundleHost.java:391)
at org.eclipse.osgi.framework.internal.core.AbstractBundle.start(AbstractBundle.java:299)
at org.eclipse.osgi.framework.internal.core.PackageAdminImpl.resumeBundles(PackageAdminImpl.java:311)
at org.eclipse.osgi.framework.internal.core.PackageAdminImpl.processDelta(PackageAdminImpl.java:555)
at org.eclipse.osgi.framework.internal.core.PackageAdminImpl.doResolveBundles(PackageAdminImpl.java:251)
at org.eclipse.osgi.framework.internal.core.PackageAdminImpl$1.run(PackageAdminImpl.java:173)
at java.lang.Thread.run(Thread.java:722)
Caused by: javax.persistence.PersistenceException: No Persistence provider for EntityManager named com.demo.persistence
at javax.persistence.Persistence.createEntityManagerFactory(Unknown Source)
at org.springframework.orm.jpa.LocalEntityManagerFactoryBean.createNativeEntityManagerFactory(LocalEntityManagerFactoryBean.java:92)
at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.afterPropertiesSet(AbstractEntityManagerFactoryBean.java:310)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory$6.run(AbstractAutowireCapableBeanFactory.java:1504)
at java.security.AccessController.doPrivileged(Native Method)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1502)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1452)
... 45 more
很抱歉这个巨大的帖子。但是我在 Manifest 文件中导出了我的持久性包,并在我的 Web 应用程序中导入了相同的包。
使用的持久性提供程序是org.eclipse.persistence.jpa.PersistenceProvider
. 这已经停止了我的项目一个月.. :(请帮忙。
提前致谢。
编辑
持久性.xml
<?xml version="1.0" encoding="UTF-8"?>
<persistence version="2.0"
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">
<persistence-unit name="com.demo.persistence"
transaction-type="RESOURCE_LOCAL">
<provider>org.eclipse.persistence.jpa.PersistenceProvider</provider>
<class>com.demo.persistence.Person</class>
<properties>
<property name="eclipselink.weaving" value="false" />
<property name="eclipselink.ddl-generation" value="create-tables" />
</properties>
</persistence-unit>
</persistence>