【问题标题】:Setup of simple Spring MVC, EclipseLink, Wildfly, Maven project搭建简单的 Spring MVC、EclipseLink、Wildfly、Maven 项目
【发布时间】:2015-04-01 00:08:07
【问题描述】:

我想用 Maven 构建一个 Spring MVC webapp,它使用 EclipseLink 作为 JPA 提供程序并在 Wildfly 应用程序服务器上运行。不幸的是,我无法让它运行。我想使用所有东西的最新版本。

当我尝试在 Wildfly 8.2 或 Tomcat 8 上运行 webapp 时出现以下错误:

01:25:11,648 警告 [org.springframework.web.context.support.XmlWebApplicationContext] (MSC 服务线程 1-1)上下文期间遇到异常 初始化 - 取消刷新尝试: org.springframework.beans.factory.BeanCreationException:

在 ServletContext 资源中创建名称为“emf”的 bean 时出错 [/WEB-INF/spring-servlet.xml]:init方法调用失败; 嵌套异常是 javax.persistence.PersistenceException:

异常 [EclipseLink-28018](Eclipse 持久性服务 - 2.6.0.v20150309-bf26070):org.eclipse.persistence.exceptions.EntityManagerSetupException 异常描述:PersistenceUnit [MovieTime] 的预部署 失败了。

内部异常:异常 [EclipseLink-28010](Eclipse 持久性 服务 - 2.6.0.v20150309-bf26070): org.eclipse.persistence.exceptions.EntityManagerSetupException 异常说明:PersistenceUnitInfo MovieTime 有 transactionType JTA,但没有定义 jtaDataSource。

谷歌搜索了很多,但我没有发现任何有用的信息。我认为persistence.xml 或pom.xml 中缺少某些内容,但我不知道是什么。 The whole exception is here.

Here is the file hierarchy of my project. (I cannot share image on SO yet)

我没有打开实体包,因为我有大约 30 个从数据库表生成的实体。

这是我的 pom.xml:

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
  <modelVersion>4.0.0</modelVersion>
  <groupId>MovieTimeProject</groupId>
  <artifactId>MovieTimeProject</artifactId>
  <packaging>war</packaging>
  <version>0.0.1-SNAPSHOT</version>
  <name>MovieTimeProject Maven Webapp</name>
  <url>http://maven.apache.org</url>

  <repositories>
        <repository>
            <id>oss.sonatype.org</id>
            <name>OSS Sonatype Staging</name>
            <url>https://oss.sonatype.org/content/groups/staging</url>
        </repository>
        <repository>
            <id>JBoss Repository</id>
            <url>https://repository.jboss.org/nexus/content/groups/public/</url>
        </repository>
  </repositories>

  <properties>
        <spring.version>4.1.6.RELEASE</spring.version>
  </properties>

  <dependencyManagement>
    <dependencies>
        <dependency>
            <groupId>org.jboss.spec</groupId>
            <artifactId>jboss-javaee-7.0</artifactId>
            <version>1.0.2.Final</version>
            <type>pom</type>
            <scope>import</scope>
        </dependency>
    </dependencies>
  </dependencyManagement>

  <dependencies>
    <!-- JUnit -->
    <dependency>
        <groupId>junit</groupId>
        <artifactId>junit</artifactId>
        <version>3.8.2</version>
        <scope>test</scope>
    </dependency>

    <!-- JBoss sever -->


    <!-- MySQL & JPA & EclipseLink -->
    <dependency>
        <groupId>mysql</groupId>
        <artifactId>mysql-connector-java</artifactId>
        <version>5.1.35</version>
    </dependency>
    <dependency>
        <groupId>org.eclipse.persistence</groupId>
        <artifactId>javax.persistence</artifactId>
        <version>2.1.0</version>
        <!-- <scope>provided</scope> --> <!-- since running inside a Java EE container -->
    </dependency>
    <dependency>
        <groupId>org.eclipse.persistence</groupId>
        <artifactId>eclipselink</artifactId>
        <version>2.6.0</version>
        <!-- <scope>provided</scope> --> <!-- Running inside a Java EE container -->
    <!-- <scope>compile</scope> -->
    </dependency>   

    <!-- Spring dependencies -->
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-core</artifactId>
        <version>${spring.version}</version>
    </dependency>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-webmvc</artifactId>
        <version>${spring.version}</version>
    </dependency>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-tx</artifactId>
        <version>${spring.version}</version>
    </dependency>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-orm</artifactId>
        <version>${spring.version}</version>
    </dependency>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-web</artifactId>
        <version>${spring.version}</version>
    </dependency>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-instrument</artifactId>
        <version>${spring.version}</version>
    </dependency>

    <!-- Servlet & jstl -->
    <dependency>
            <groupId>jstl</groupId>
            <artifactId>jstl</artifactId>
            <version>1.2</version>
        </dependency>
    <dependency>
        <groupId>javax.servlet</groupId>
        <artifactId>javax.servlet-api</artifactId>
        <version>3.1.0</version>
    </dependency>
    <dependency>
        <groupId>javax.servlet.jsp</groupId>
        <artifactId>javax.servlet.jsp-api</artifactId>
        <version>2.3.2-b01</version>
    </dependency>


    <dependency>
        <groupId>aopalliance</groupId>
        <artifactId>aopalliance</artifactId>
        <version>1.0</version>
    </dependency>
    <dependency>
        <groupId>cglib</groupId>
        <artifactId>cglib</artifactId>
        <version>3.1</version>
    </dependency>


    <dependency>
        <groupId>aspectj</groupId>
        <artifactId>aspectjrt</artifactId>
        <version>1.5.4</version>
    </dependency>
    <dependency>
        <groupId>org.aspectj</groupId>
        <artifactId>aspectjweaver</artifactId>
        <version>1.8.5</version>
    </dependency>
  </dependencies>
  <build>
    <plugins>
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-compiler-plugin</artifactId>
            <version>3.1</version>
            <configuration>
                <source>1.8</source>
                <target>1.8</target>
            </configuration>
        </plugin>

    </plugins>
    <finalName>MovieTimeProject</finalName>
  </build>
</project>

这里是persistence.xml:

<?xml version="1.0" encoding="UTF-8"?>
<persistence version="2.1" xmlns="http://xmlns.jcp.org/xml/ns/persistence" 
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/persistence http://xmlns.jcp.org/xml/ns/persistence/persistence_2_1.xsd">
    <persistence-unit name="MovieTime" transaction-type="JTA">
        <provider>org.eclipse.persistence.jpa.PersistenceProvider</provider>
        <properties>
                <property name="javax.persistence.jdbc.driver" value="com.mysql.jdbc.Driver"/>
                <property name="javax.persistence.jdbc.url" value="jdbc:mysql://localhost:3306/movietime2"/>
                <property name="javax.persistence.jdbc.user" value="root"/>
                <property name="javax.persistence.jdbc.password" value="root"/>
        </properties>
    </persistence-unit>
</persistence>

web.xml:

<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns="http://xmlns.jcp.org/xml/ns/javaee"
    xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
    id="WebApp_ID" version="3.1">
  <display-name>MovieTime!</display-name>

  <welcome-file-list>
    <welcome-file>index.jsp</welcome-file>
  </welcome-file-list>

  <servlet>
    <servlet-name>spring</servlet-name>
    <servlet-class>
        org.springframework.web.servlet.DispatcherServlet
    </servlet-class>
    <load-on-startup>1</load-on-startup>
    <!-- 
    <init-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>src/main/webapp/WEB-INF/dispatcher-servlet.xml</param-value>
    </init-param>
     -->
  </servlet>
  <servlet-mapping>
    <servlet-name>spring</servlet-name>
    <!-- <url-pattern>/</url-pattern> -->
    <url-pattern>/</url-pattern>
  </servlet-mapping>

  <!-- 
  <context-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>src/main/webapp/WEB-INF/applicationContext.xml</param-value>
  </context-param>
  -->

  <!-- Creates the Spring Container shared by all Servlets and Filters -->
  <!-- 
  <listener>
    <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
  </listener>
    -->

</web-app>

spring-servlet.xml:

<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:mvc="http://www.springframework.org/schema/mvc"
    xmlns:context="http://www.springframework.org/schema/context"
    xmlns:aop="http://www.springframework.org/schema/aop"
    xmlns:tx="http://www.springframework.org/schema/tx"
    xsi:schemaLocation="
    http://www.springframework.org/schema/beans     
    http://www.springframework.org/schema/beans/spring-beans.xsd
    http://www.springframework.org/schema/context
    http://www.springframework.org/schema/context/spring-context.xsd
    http://www.springframework.org/schema/mvc
    http://www.springframework.org/schema/mvc/spring-mvc.xsd
    http://www.springframework.org/schema/aop
    http://www.springframework.org/schema/aop/spring-aop-3.0.xsd
    http://www.springframework.org/schema/tx
    http://www.springframework.org/schema/tx/spring-tx-3.0.xsd">

    <!-- Use @Component annotations for bean definitions -->
    <context:component-scan base-package="com.movietime.controller" />

    <!-- Use @Controller annotations for MVC controller definitions -->
    <mvc:annotation-driven enable-matrix-variables="true"/>


    <!-- Add JPA support -->
     <bean id="emf" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
        <property name="loadTimeWeaver">
           <bean class="org.springframework.instrument.classloading.InstrumentationLoadTimeWeaver"/>
         </property>
     </bean>

     <!-- Add Transaction support -->
    <bean id="myTxManager"
       class="org.springframework.orm.jpa.JpaTransactionManager">
          <property name="entityManagerFactory" ref="emf"/>
    </bean>

    <!-- Use @Transaction annotations for managing transactions -->
    <tx:annotation-driven transaction-manager="myTxManager" />

    <!-- View resolver -->
    <bean class=
        "org.springframework.web.servlet.view.InternalResourceViewResolver">
      <property name="prefix" value="/WEB-INF/"/>
    </bean>



    <!-- Resolves views selected for rendering by @Controllers to .jsp resources in the /WEB-INF/pages directory -->
    <!-- 
    <bean id="viewResolver"
        class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <property name="prefix">
            <value>/WEB-INF/pages/</value>
        </property>
        <property name="suffix">
            <value>.jsp</value>
        </property>     
    </bean>
     -->

    <!-- Configure to plugin JSON as request and response in method handler -->
    <!-- 
    <bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter">
        <property name="messageConverters">
            <list>
                <ref bean="jsonMessageConverter"/>
            </list>
        </property>
    </bean>
      -->

    <!-- Configure bean to convert JSON to POJO and vice versa -->
    <!-- 
    <bean id="jsonMessageConverter" class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter"/>
     -->

</beans>

HelloController.java:

package com.movietime.controller;

import java.util.List;

import javax.annotation.Resource;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.ModelAndView;

import com.movietime.entities.Movie;
import com.movietime.dataAccessLayer.MovieService;;

/**
 * @author Attila
 * 
 * Presentation layer (MVC) / Controller
 */
@Controller
public class HelloController {

    @Resource
    MovieService service;

    @RequestMapping("/index")
    public ModelAndView welcomePage() {

        List<Movie> result = service.findByTitle("The eternal sunshine of");
        System.out.println(result.get(0));

        return new ModelAndView("index.jsp");
    }
}

MovieService.java:

package com.movietime.dataAccessLayer;

import java.util.List;

import javax.annotation.Resource;

import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.movietime.dao.MovieRepository;
import com.movietime.entities.Movie;

@Service
public class MovieService {

    @Resource
    private MovieRepository movieRepository;

    @Transactional(readOnly = true)
    public List<Movie> findByTitle(String title) {

        List<Movie> result = movieRepository.findMoviesByTitle(title); 
        return result;
    }
}

MovieRepository.java:

package com.movietime.dao;

import java.util.List;

import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.Query;

import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Repository;
import org.springframework.transaction.annotation.Transactional;

import com.movietime.entities.Movie;

@Repository
@Scope(value="singleton")
public class MovieRepository {

    @PersistenceContext
    private EntityManager em;

    @Transactional
    public void register(Movie mov) {
        // Save employee
        this.em.persist(mov);
    }


    @SuppressWarnings("unchecked")
    public List<Movie> findMoviesByTitle(String title) {

        String queryString = "SELECT m FROM Movie m WHERE m.title LIKE '" + title + "%'";
        Query query = em.createQuery(queryString, Movie.class);

        return query.getResultList();
    }

}

【问题讨论】:

  • 如异常中所述,您需要在persistence.xml文件的中提供一个元素,并在应用程序中配置数据源的名称服务器。您可以参考docs.oracle.com/javaee/7/tutorial/persistence-intro003.htm 的 Java EE 教程
  • 或者,您可以将 transaction-type 切换为 RESOURCE_LOCAL 并在 persistence.xml 中提供与数据库的连接,这已在您的文件中实现。
  • 目前我没有足够的时间来开发这个应用程序。一旦我可以继续,我会发布一个回答。谢谢佩特罗斯!

标签: maven spring-mvc eclipselink wildfly-8


【解决方案1】:

好的,我通过将事务类型更改为 RESOURCE_LOCAL 解决了这个错误。

【讨论】: