I'm trying to use Spring 3.2 and Spring Data on GAE and having some trouble getting my configuration right. It's minimal but from the Spring Data documentation it seems like you don't need much more than just the entitymanagerfactory bean.
Here's my configuration and the exception I am getting at startup. Can someone please provide a solution for the exception I am receiving with Datanucleus JPA 2.0?
pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<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/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<packaging>war</packaging>
<version>1.0.0-SNAPSHOT</version>
<groupId>com.foo</groupId>
<artifactId>bar</artifactId>
<properties>
<appengine.version>1.7.5</appengine.version>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<slf4j.version>1.7.2</slf4j.version>
<datanucleus.version>3.0.6</datanucleus.version>
<spring.version>3.2.1.RELEASE</spring.version>
<spring-data.version>1.3.0.RELEASE</spring-data.version>
</properties>
<dependencies>
<!-- Compile/runtime dependencies -->
<dependency>
<groupId>com.google.appengine</groupId>
<artifactId>appengine-api-1.0-sdk</artifactId>
<version>${appengine.version}</version>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>servlet-api</artifactId>
<version>2.5</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>jstl</groupId>
<artifactId>jstl</artifactId>
<version>1.2</version>
</dependency>
<!-- Spring -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</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-webmvc</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-jpa</artifactId>
<version>${spring-data.version}</version>
</dependency>
<!-- Logging dependencies -->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-jdk14</artifactId>
<version>${slf4j.version}</version>
</dependency>
<!-- JPA 2.0 for GAE -->
<dependency>
<groupId>com.google.appengine.orm</groupId>
<artifactId>datanucleus-appengine</artifactId>
<version>2.0.0</version>
</dependency>
<dependency>
<groupId>org.datanucleus</groupId>
<artifactId>datanucleus-api-jpa</artifactId>
<version>${datanucleus.version}</version>
</dependency>
<dependency>
<groupId>org.datanucleus</groupId>
<artifactId>datanucleus-core</artifactId>
<version>${datanucleus.version}</version>
</dependency>
<dependency>
<groupId>org.apache.geronimo.specs</groupId>
<artifactId>geronimo-jpa_2.0_spec</artifactId>
<version>1.0</version>
</dependency>
<!-- Test Dependencies -->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.10</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-all</artifactId>
<version>1.9.0</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.google.appengine</groupId>
<artifactId>appengine-testing</artifactId>
<version>${appengine.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.google.appengine</groupId>
<artifactId>appengine-api-stubs</artifactId>
<version>${appengine.version}</version>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<version>2.5.1</version>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>1.6</source>
<target>1.6</target>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<version>2.3</version>
<configuration>
<archiveClasses>true</archiveClasses>
<webResources>
<!-- in order to interpolate version from pom into appengine-web.xml -->
<resource>
<directory>${basedir}/src/main/webapp/WEB-INF</directory>
<filtering>true</filtering>
<targetPath>WEB-INF</targetPath>
</resource>
</webResources>
</configuration>
</plugin>
<plugin>
<groupId>com.google.appengine</groupId>
<artifactId>appengine-maven-plugin</artifactId>
<version>${appengine.version}</version>
</plugin>
</plugins>
</build>
</project>
JPA Configuration
@Configuration
@EnableJpaRepositories("com.foo.bar.domain")
@EnableTransactionManagement
class JpaApplicationConfig {
private static final Logger logger = Logger
.getLogger(JpaApplicationConfig.class.getName());
@Bean
public EntityManagerFactory entityManagerFactory() {
logger.info("Loading Entity Manager...");
return Persistence
.createEntityManagerFactory("eventual-reads-short-deadlines");
}
@Bean
public PlatformTransactionManager transactionManager() {
logger.info("Loading Transaction Manager...");
final JpaTransactionManager txManager = new JpaTransactionManager();
txManager.setEntityManagerFactory(entityManagerFactory());
return txManager;
}
}
Exception
[INFO] SEVERE: Context initialization failed
[INFO] org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor#0': Initialization of bean failed; nested exception is java.lang.IllegalStateException: No persistence exception translators found in bean factory. Cannot perform exception translation.
[INFO] at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:532)
[INFO] at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:461)
[INFO] at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:295)
[INFO] at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:223)
[INFO] at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:292)
[INFO] at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:198)
[INFO] at org.springframework.context.support.AbstractApplicationContext.registerBeanPostProcessors(AbstractApplicationContext.java:741)
[INFO] at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:464)
[INFO] at org.springframework.web.context.ContextLoader.configureAndRefreshWebApplicationContext(ContextLoader.java:389)
[INFO] at org.springframework.web.context.ContextLoader.initWebApplicationContext(ContextLoader.java:294)
[INFO] at org.springframework.web.context.ContextLoaderListener.contextInitialized(ContextLoaderListener.java:112)
[INFO] at org.mortbay.jetty.handler.ContextHandler.startContext(ContextHandler.java:548)
[INFO] at org.mortbay.jetty.servlet.Context.startContext(Context.java:136)
[INFO] at org.mortbay.jetty.webapp.WebAppContext.startContext(WebAppContext.java:1250)
[INFO] at org.mortbay.jetty.handler.ContextHandler.doStart(ContextHandler.java:517)
[INFO] at org.mortbay.jetty.webapp.WebAppContext.doStart(WebAppContext.java:467)
[INFO] at org.mortbay.component.AbstractLifeCycle.start(AbstractLifeCycle.java:50)
[INFO] at org.mortbay.jetty.handler.HandlerWrapper.doStart(HandlerWrapper.java:130)
[INFO] at org.mortbay.component.AbstractLifeCycle.start(AbstractLifeCycle.java:50)
[INFO] at org.mortbay.jetty.handler.HandlerWrapper.doStart(HandlerWrapper.java:130)
[INFO] at org.mortbay.jetty.Server.doStart(Server.java:224)
[INFO] at org.mortbay.component.AbstractLifeCycle.start(AbstractLifeCycle.java:50)
[INFO] at com.google.appengine.tools.development.JettyContainerService.startContainer(JettyContainerService.java:228)
[INFO] at com.google.appengine.tools.development.AbstractContainerService.startup(AbstractContainerService.java:255)
[INFO] at com.google.appengine.tools.development.AbstractServer.startup(AbstractServer.java:79)
[INFO] at com.google.appengine.tools.development.DevAppServerImpl$Servers.startup(DevAppServerImpl.java:451)
[INFO] at com.google.appengine.tools.development.DevAppServerImpl.start(DevAppServerImpl.java:198)
[INFO] at com.google.appengine.tools.development.DevAppServerMain$StartAction.apply(DevAppServerMain.java:333)
[INFO] at com.google.appengine.tools.util.Parser$ParseResult.applyArgs(Parser.java:48)
[INFO] at com.google.appengine.tools.development.DevAppServerMain.<init>(DevAppServerMain.java:269)
[INFO] at com.google.appengine.tools.development.DevAppServerMain.main(DevAppServerMain.java:245)
[INFO] Caused by: java.lang.IllegalStateException: No persistence exception translators found in bean factory. Cannot perform exception translation.
[INFO] at org.springframework.dao.support.PersistenceExceptionTranslationInterceptor.detectPersistenceExceptionTranslators(PersistenceExceptionTranslationInterceptor.java:142)
[INFO] at org.springframework.dao.support.PersistenceExceptionTranslationInterceptor.<init>(PersistenceExceptionTranslationInterceptor.java:79)
[INFO] at org.springframework.dao.annotation.PersistenceExceptionTranslationAdvisor.<init>(PersistenceExceptionTranslationAdvisor.java:70)
[INFO] at org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor.setBeanFactory(PersistenceExceptionTranslationPostProcessor.java:103)
[INFO] at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeAwareMethods(AbstractAutowireCapableBeanFactory.java:1506)
[INFO] at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.access$000(AbstractAutowireCapableBeanFactory.java:116)
[INFO] at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory$5.run(AbstractAutowireCapableBeanFactory.java:1468)
[INFO] at java.security.AccessController.doPrivileged(Native Method)
[INFO] at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1466)
[INFO] at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:524)
[INFO] ... 30 more
[INFO]
[INFO] Mar 12, 2013 11:10:49 AM com.google.apphosting.utils.jetty.JettyLogger warn
[INFO] WARNING: Failed startup of context com.google.appengine.tools.development.DevAppEngineWebAppContext@2912ee3c{/,/home/tim/workspace-me/Dating/target/dating-1.0.0-SNAPSHOT}
[INFO] org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor#0': Initialization of bean failed; nested exception is java.lang.IllegalStateException: No persistence exception translators found in bean factory. Cannot perform exception translation.
[INFO] at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:532)
[INFO] at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:461)
[INFO] at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:295)
[INFO] at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:223)
[INFO] at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:292)
[INFO] at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:198)
[INFO] at org.springframework.context.support.AbstractApplicationContext.registerBeanPostProcessors(AbstractApplicationContext.java:741)
[INFO] at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:464)
[INFO] at org.springframework.web.context.ContextLoader.configureAndRefreshWebApplicationContext(ContextLoader.java:389)
[INFO] at org.springframework.web.context.ContextLoader.initWebApplicationContext(ContextLoader.java:294)
[INFO] at org.springframework.web.context.ContextLoaderListener.contextInitialized(ContextLoaderListener.java:112)
[INFO] at org.mortbay.jetty.handler.ContextHandler.startContext(ContextHandler.java:548)
[INFO] at org.mortbay.jetty.servlet.Context.startContext(Context.java:136)
[INFO] at org.mortbay.jetty.webapp.WebAppContext.startContext(WebAppContext.java:1250)
[INFO] at org.mortbay.jetty.handler.ContextHandler.doStart(ContextHandler.java:517)
[INFO] at org.mortbay.jetty.webapp.WebAppContext.doStart(WebAppContext.java:467)
[INFO] at org.mortbay.component.AbstractLifeCycle.start(AbstractLifeCycle.java:50)
[INFO] at org.mortbay.jetty.handler.HandlerWrapper.doStart(HandlerWrapper.java:130)
[INFO] at org.mortbay.component.AbstractLifeCycle.start(AbstractLifeCycle.java:50)
[INFO] at org.mortbay.jetty.handler.HandlerWrapper.doStart(HandlerWrapper.java:130)
[INFO] at org.mortbay.jetty.Server.doStart(Server.java:224)
[INFO] at org.mortbay.component.AbstractLifeCycle.start(AbstractLifeCycle.java:50)
[INFO] at com.google.appengine.tools.development.JettyContainerService.startContainer(JettyContainerService.java:228)
[INFO] at com.google.appengine.tools.development.AbstractContainerService.startup(AbstractContainerService.java:255)
[INFO] at com.google.appengine.tools.development.AbstractServer.startup(AbstractServer.java:79)
[INFO] at com.google.appengine.tools.development.DevAppServerImpl$Servers.startup(DevAppServerImpl.java:451)
[INFO] at com.google.appengine.tools.development.DevAppServerImpl.start(DevAppServerImpl.java:198)
[INFO] at com.google.appengine.tools.development.DevAppServerMain$StartAction.apply(DevAppServerMain.java:333)
[INFO] at com.google.appengine.tools.util.Parser$ParseResult.applyArgs(Parser.java:48)
[INFO] at com.google.appengine.tools.development.DevAppServerMain.<init>(DevAppServerMain.java:269)
[INFO] at com.google.appengine.tools.development.DevAppServerMain.main(DevAppServerMain.java:245)
[INFO] Caused by: java.lang.IllegalStateException: No persistence exception translators found in bean factory. Cannot perform exception translation.
[INFO] at org.springframework.dao.support.PersistenceExceptionTranslationInterceptor.detectPersistenceExceptionTranslators(PersistenceExceptionTranslationInterceptor.java:142)
[INFO] at org.springframework.dao.support.PersistenceExceptionTranslationInterceptor.<init>(PersistenceExceptionTranslationInterceptor.java:79)
[INFO] at org.springframework.dao.annotation.PersistenceExceptionTranslationAdvisor.<init>(PersistenceExceptionTranslationAdvisor.java:70)
[INFO] at org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor.setBeanFactory(PersistenceExceptionTranslationPostProcessor.java:103)
[INFO] at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeAwareMethods(AbstractAutowireCapableBeanFactory.java:1506)
[INFO] at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.access$000(AbstractAutowireCapableBeanFactory.java:116)
[INFO] at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory$5.run(AbstractAutowireCapableBeanFactory.java:1468)
[INFO] at java.security.AccessController.doPrivileged(Native Method)
[INFO] at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1466)
[INFO] at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:524)
[INFO] ... 30 more
[INFO]
[INFO] Mar 12, 2013 11:10:49 AM com.google.apphosting.utils.jetty.JettyLogger warn
[INFO] WARNING: Nested in org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor#0': Initialization of bean failed; nested exception is java.lang.IllegalStateException: No persistence exception translators found in bean factory. Cannot perform exception translation.:
[INFO] java.lang.IllegalStateException: No persistence exception translators found in bean factory. Cannot perform exception translation.
[INFO] at org.springframework.dao.support.PersistenceExceptionTranslationInterceptor.detectPersistenceExceptionTranslators(PersistenceExceptionTranslationInterceptor.java:142)
[INFO] at org.springframework.dao.support.PersistenceExceptionTranslationInterceptor.<init>(PersistenceExceptionTranslationInterceptor.java:79)
[INFO] at org.springframework.dao.annotation.PersistenceExceptionTranslationAdvisor.<init>(PersistenceExceptionTranslationAdvisor.java:70)
[INFO] at org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor.setBeanFactory(PersistenceExceptionTranslationPostProcessor.java:103)
[INFO] at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeAwareMethods(AbstractAutowireCapableBeanFactory.java:1506)
[INFO] at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.access$000(AbstractAutowireCapableBeanFactory.java:116)
[INFO] at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory$5.run(AbstractAutowireCapableBeanFactory.java:1468)
[INFO] at java.security.AccessController.doPrivileged(Native Method)
[INFO] at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1466)
[INFO] at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:524)
[INFO] at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:461)
[INFO] at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:295)
[INFO] at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:223)
[INFO] at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:292)
[INFO] at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:198)
[INFO] at org.springframework.context.support.AbstractApplicationContext.registerBeanPostProcessors(AbstractApplicationContext.java:741)
[INFO] at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:464)
[INFO] at org.springframework.web.context.ContextLoader.configureAndRefreshWebApplicationContext(ContextLoader.java:389)
[INFO] at org.springframework.web.context.ContextLoader.initWebApplicationContext(ContextLoader.java:294)
[INFO] at org.springframework.web.context.ContextLoaderListener.contextInitialized(ContextLoaderListener.java:112)
[INFO] at org.mortbay.jetty.handler.ContextHandler.startContext(ContextHandler.java:548)
[INFO] at org.mortbay.jetty.servlet.Context.startContext(Context.java:136)
[INFO] at org.mortbay.jetty.webapp.WebAppContext.startContext(WebAppContext.java:1250)
[INFO] at org.mortbay.jetty.handler.ContextHandler.doStart(ContextHandler.java:517)
[INFO] at org.mortbay.jetty.webapp.WebAppContext.doStart(WebAppContext.java:467)
[INFO] at org.mortbay.component.AbstractLifeCycle.start(AbstractLifeCycle.java:50)
[INFO] at org.mortbay.jetty.handler.HandlerWrapper.doStart(HandlerWrapper.java:130)
[INFO] at org.mortbay.component.AbstractLifeCycle.start(AbstractLifeCycle.java:50)
[INFO] at org.mortbay.jetty.handler.HandlerWrapper.doStart(HandlerWrapper.java:130)
[INFO] at org.mortbay.jetty.Server.doStart(Server.java:224)
[INFO] at org.mortbay.component.AbstractLifeCycle.start(AbstractLifeCycle.java:50)
[INFO] at com.google.appengine.tools.development.JettyContainerService.startContainer(JettyContainerService.java:228)
[INFO] at com.google.appengine.tools.development.AbstractContainerService.startup(AbstractContainerService.java:255)
[INFO] at com.google.appengine.tools.development.AbstractServer.startup(AbstractServer.java:79)
[INFO] at com.google.appengine.tools.development.DevAppServerImpl$Servers.startup(DevAppServerImpl.java:451)
[INFO] at com.google.appengine.tools.development.DevAppServerImpl.start(DevAppServerImpl.java:198)
[INFO] at com.google.appengine.tools.development.DevAppServerMain$StartAction.apply(DevAppServerMain.java:333)
[INFO] at com.google.appengine.tools.util.Parser$ParseResult.applyArgs(Parser.java:48)
[INFO] at com.google.appengine.tools.development.DevAppServerMain.<init>(DevAppServerMain.java:269)
[INFO] at com.google.appengine.tools.development.DevAppServerMain.main(DevAppServerMain.java:245)
[INFO]
[INFO] Mar 12, 2013 11:10:49 AM com.google.apphosting.utils.jetty.JettyLogger debug
In standalone environments we recommend to use the Spring support classes to set up a
EntityManagerFactory
. So if you change your configuration to the following the additional bean declaration should not be necessary:The crucial part is making the
FactoryBean
implementation available as Spring bean as it implementsPersistenceExceptionTranslator
.I found a solution, but it's not the most favorable in my opinion. I added to my config:
I haven't begun to test if this works, but it stops the exception from being thrown. I'd prefer to use a Datanucleus specific translator, but I don't know if one exists. Additional solutions are welcome.