37

Spring Boot doesn't work with Google App Engine (at least not for me).

However much of the examples written or available in the GitHub or other repositories are using Spring Boot, is there any example for Spring-Data-JPA that does not use Spring Boot and use plain context XML as before?

That will show

- spring/context.xml (or servlet-context.xml)

quarks
  • 33,478
  • 73
  • 290
  • 513
  • 4
    Pretty close to what you are asking for (with the difference that Java Config is used in most cases instead of XML) are the tutorials in this series http://www.petrikainulainen.net/programming/spring-framework/spring-data-jpa-tutorial-part-one-configuration/ – geoand May 31 '14 at 21:06
  • 2
    [http://www.springbyexample.org/examples/spring-data-jpa.html](http://www.springbyexample.org/examples/spring-data-jpa.html) – Andrei Stefan May 31 '14 at 21:29
  • 2
    If you're interested here's a GAE sample with Spring Boot: https://github.com/scratches/spring-boot-sample-gae. Why you'd want to use XML is not really very clear, but note that there's nothing stopping you from using Spring Boot with XML either. – Dave Syer Jun 01 '14 at 06:16
  • @DaveSyer this spring-boot-sample-gae does not work as far as I know when I tested it – quarks Jun 01 '14 at 15:48
  • 2
    It *did* work. If you want to fix it and send a pull request, be my guest. – Dave Syer Jun 01 '14 at 17:35
  • @DaveSyer Let me try again, I wonder why you are using gae:deploy, does it mean that it can't run locally (with the SDK)? – quarks Jun 02 '14 at 02:31
  • @DaveSyer the problem I get is: [INFO] java.lang.NoClassDefFoundError: java.io.FileOutputStream is a restricted class. Please see the Google App Engine developer's guide for more details. – quarks Jun 02 '14 at 02:48
  • 1
    I don't see that problem, and the app is working fine (deployed it yesterday from master). – Dave Syer Jun 03 '14 at 07:42

3 Answers3

35

Just created this example for you:

src/main/webapp/WEB-INF/spring/context.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:p="http://www.springframework.org/schema/p"
    xmlns:context="http://www.springframework.org/schema/context" xmlns:tx="http://www.springframework.org/schema/tx"
    xmlns:jpa="http://www.springframework.org/schema/data/jpa"
    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/tx http://www.springframework.org/schema/tx/spring-tx.xsd
        http://www.springframework.org/schema/data/jpa http://www.springframework.org/schema/data/jpa/spring-jpa.xsd">

    <context:property-placeholder location="/WEB-INF/spring/jdbc.properties" />

    <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource"
        p:driverClassName="${jdbc.driverClassName}" p:url="${jdbc.url}"
        p:username="${jdbc.username}" p:password="${jdbc.password}" />

    <bean id="hibernateJpaVendorAdapter"
        class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter" />

    <!-- Configure the entity manager factory bean -->
    <bean id="entityManagerFactory"
        class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
        <property name="dataSource" ref="dataSource" />
        <property name="jpaVendorAdapter" ref="hibernateJpaVendorAdapter" />
        <!-- Set JPA properties -->
        <property name="jpaProperties">
            <props>
                <prop key="hibernate.dialect">${hibernate.dialect}</prop>
            </props>
        </property>
        <property name="packagesToScan" value="com.demo.data" />
    </bean>

    <!-- Configure the transaction manager bean -->
    <bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
        <property name="entityManagerFactory" ref="entityManagerFactory" />
    </bean>

    <tx:annotation-driven />

    <jpa:repositories base-package="com.demo.data" />
    <context:component-scan base-package="com.demo.svc" />
</beans>

/src/main/webapp/WEB-INF/spring/jdbc.properties

# JDBC Connection
jdbc.driverClassName=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://host:3306/db
jdbc.username=user
jdbc.password=password
hibernate.dialect=org.hibernate.dialect.MySQLDialect

/src/main/webapp/WEB-INF/spring/servlet-context.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans:beans xmlns="http://www.springframework.org/schema/mvc"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:beans="http://www.springframework.org/schema/beans"
    xmlns:context="http://www.springframework.org/schema/context"
    xsi:schemaLocation="http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd
        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">

    <context:component-scan base-package="com.demo.web" />
</beans:beans>

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"
    version="2.5">
    <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>/WEB-INF/spring/context.xml</param-value>
    </context-param>
    <context-param>
        <param-name>webAppRootKey</param-name>
        <param-value>demo_jpa</param-value>
    </context-param>

    <listener>
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    </listener>
    <servlet>
        <servlet-name>appServlet</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <init-param>
            <param-name>contextConfigLocation</param-name>
            <param-value>/WEB-INF/spring/servlet-context.xml</param-value>
        </init-param>
        <load-on-startup>1</load-on-startup>
    </servlet>
    <servlet-mapping>
        <servlet-name>appServlet</servlet-name>
        <url-pattern>/</url-pattern>
    </servlet-mapping>
</web-app>

pom.xml

<properties>
    <org.springframework-version>4.1.7.RELEASE</org.springframework-version>
    <org.hibernate-em-version>4.3.8.Final</org.hibernate-em-version>
    <org.springframework.data-version>1.9.0.RELEASE</org.springframework.data-version>
    <dbcp-version>1.4</dbcp-version>
    <mysql-connector-version>5.1.28</mysql-connector-version>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>

<dependencies>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-context-support</artifactId>
        <version>${org.springframework-version}</version>
    </dependency>

    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-webmvc</artifactId>
        <version>${org.springframework-version}</version>
    </dependency>

    <dependency>
        <groupId>org.springframework.data</groupId>
        <artifactId>spring-data-jpa</artifactId>
        <version>${org.springframework.data-version}</version>
    </dependency>

    <dependency>
        <groupId>org.hibernate</groupId>
        <artifactId>hibernate-entitymanager</artifactId>
        <version>${org.hibernate-em-version}</version>
    </dependency>

    <dependency>
        <groupId>mysql</groupId>
        <artifactId>mysql-connector-java</artifactId>
        <version>${mysql-connector-version}</version>
    </dependency>

    <dependency>
        <groupId>commons-dbcp</groupId>
        <artifactId>commons-dbcp</artifactId>
        <version>${dbcp-version}</version>
    </dependency>
</dependencies>

Data Entity: com.demo.data.User

package com.demo.data;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;

@Entity
@Table(name = "SYS_USERS")
public class User {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "USER_ID")
    private int id;

    @Column(name = "USER_NAME")
    private String name;

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}

Spring Data JPA Repository: com.demo.data.UserRepository

package com.demo.data;

import org.springframework.data.repository.CrudRepository;

public interface UserRepository extends CrudRepository<User, Integer> {
}

Service

Interface:

package com.demo.svc;

import com.demo.data.User;

public interface UserService {
    User findUserById(Integer id);
}

Implementation:

package com.demo.svc;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.demo.data.User;
import com.demo.data.UserRepository;

@Service
public class UserServiceImpl implements UserService {
    @Autowired
    UserRepository userRepository;

    public User findUserById(Integer id) {
        return userRepository.findOne(id);
    }
}

Web Controller: com.demo.web.UserController

package com.demo.web;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import com.demo.svc.UserService;

@Controller
public class UserController {
    @Autowired
    UserService svc;

    @RequestMapping("/")
    @ResponseBody
    public String test() {
        return svc.findUserById(1).getName();
    }
}
JM Yang
  • 1,208
  • 9
  • 14
  • 2
    Hi @JM Yang , please i follow your example , bu when i start the application i got the following error : org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'userRepository': Injection of persistence dependencies failed; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [javax.persistence.EntityManagerFactory] do you have any idea about the error ? Regards ! – James May 22 '18 at 14:40
1

This is happening because you haven't created the bean of UserRepository in context. There are a number of ways you can do this since you're not using a spring boot project so it won't make an object in the container at startup due to which @Autowired is not injecting the object in the UserRepository class. For this project, you can update the following in your project:

 package com.demo.svc;

 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;

 import com.demo.data.User;
 import com.demo.data.UserRepository;

 @Service
 public class UserServiceImpl implements UserService {

 UserRepository userRepository;

 public User findUserById(Integer id) {
     return userRepository.findOne(id);
 }

  public UserRepository setRepo(UserRepository repo)
  {
    userRepository=repo;
  }

}

Also, you'll need to inject the object from the container. In src/main/webapp/WEB-INF/spring/context.xml

<bean id="repo" class="com.demo.data.UserRepository"></bean>

<!--Setting the object ref in com.demo.svc.UserServiceImpl-->

<bean id="userserviceImpl" class="com.demo.svc.UserServiceImpl">
 <property name="userRepository" ref="repo"></property>
 </bean>

Hope it helps

Amit Mishra
  • 498
  • 5
  • 16
0

Adding this should solve your problem: javax.servlet servlet-api 2.5 provided Or, if you are using servlet 3.1 (or 3.0.1), you can use something like: javax.servlet javax.servlet-api 3.1.0 provided