设置简单 Spring MVC、EclipseLink、Wildfly、Maven 项目

Setup of simple Spring MVC, EclipseLink, Wildfly, Maven project

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

当我尝试 运行 Wildfly 8.2 或 Tomcat 8 上的网络应用程序时出现以下错误:

01:25:11,648 WARN [org.springframework.web.context.support.XmlWebApplicationContext] (MSC service thread 1-1) Exception encountered during context initialization - cancelling refresh attempt: org.springframework.beans.factory.BeanCreationException:

Error creating bean with name 'emf' defined in ServletContext resource [/WEB-INF/spring-servlet.xml]: Invocation of init method failed; nested exception is javax.persistence.PersistenceException:

Exception [EclipseLink-28018] (Eclipse Persistence Services - 2.6.0.v20150309-bf26070): org.eclipse.persistence.exceptions.EntityManagerSetupException Exception Description: Predeployment of PersistenceUnit [MovieTime] failed.

Internal Exception: Exception [EclipseLink-28010] (Eclipse Persistence Services - 2.6.0.v20150309-bf26070): org.eclipse.persistence.exceptions.EntityManagerSetupException Exception Description: PersistenceUnitInfo MovieTime has transactionType JTA, but does not have a jtaDataSource defined.

A 在 Google 上搜索了很多,但没有找到任何有用的信息。我认为 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();
    }

}

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