Spring Java Config创建在类路径资源中定义名为'entityManagerFactory'的bean时出错

时间:2014-05-25 15:48:09

标签: spring jpa entitymanager

我正在尝试将xml应用程序配置文件转换为基于Java的配置。 我遇到了entityManager的问题。它与persistence.xml和web.xml

配合得很好
<!-- Entity Manager -->
<jee:jndi-lookup id="entityManagerFactory" jndi-name="jdbc/derby"></jee:jndi-lookup>

我用

  • Spring 3.2
  • maven 3
  • Java 7
  • glassfish embedded 3.1.1
  • Spring Data JPA 1.4.2
你可以帮帮我吗?谢谢!

堆栈跟踪

mai 27, 2014 11:19:57 PM org.apache.catalina.core.ContainerBase addChildInternal
Grave: ContainerBase.addChild: start: 
org.apache.catalina.LifecycleException: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'entityManagerFactory' defined in class path resource [com/marc/embeddedglassfish/config/PersistenceContext.class]: Invocation of init method failed; nested exception is java.lang.reflect.UndeclaredThrowableException
    at org.apache.catalina.core.StandardContext.start(StandardContext.java:5389)
    at com.sun.enterprise.web.WebModule.start(WebModule.java:498)
    at org.apache.catalina.core.ContainerBase.addChildInternal(ContainerBase.java:917)
    at org.apache.catalina.core.ContainerBase.addChild(ContainerBase.java:901)
    at org.apache.catalina.core.StandardHost.addChild(StandardHost.java:733)
    at com.sun.enterprise.web.WebContainer.loadWebModule(WebContainer.java:2000)
    at com.sun.enterprise.web.WebContainer.loadWebModule(WebContainer.java:1651)
    at com.sun.enterprise.web.WebApplication.start(WebApplication.java:109)
    at org.glassfish.internal.data.EngineRef.start(EngineRef.java:130)
    at org.glassfish.internal.data.ModuleInfo.start(ModuleInfo.java:269)
    at org.glassfish.internal.data.ApplicationInfo.start(ApplicationInfo.java:294)
    at com.sun.enterprise.v3.server.ApplicationLifecycle.deploy(ApplicationLifecycle.java:462)
    at com.sun.enterprise.v3.server.ApplicationLifecycle.deploy(ApplicationLifecycle.java:240)
    at org.glassfish.deployment.admin.DeployCommand.execute(DeployCommand.java:382)
    at com.sun.enterprise.v3.admin.CommandRunnerImpl$1.execute(CommandRunnerImpl.java:355)
    at com.sun.enterprise.v3.admin.CommandRunnerImpl.doCommand(CommandRunnerImpl.java:370)
    at com.sun.enterprise.v3.admin.CommandRunnerImpl.doCommand(CommandRunnerImpl.java:1064)
    at com.sun.enterprise.v3.admin.CommandRunnerImpl.access$1200(CommandRunnerImpl.java:96)
    at com.sun.enterprise.v3.admin.CommandRunnerImpl$ExecutionContext.execute(CommandRunnerImpl.java:1244)
    at com.sun.enterprise.v3.admin.CommandRunnerImpl$ExecutionContext.execute(CommandRunnerImpl.java:1232)
    at com.sun.enterprise.admin.cli.embeddable.DeployerImpl.deploy(DeployerImpl.java:129)
    at com.sun.enterprise.admin.cli.embeddable.DeployerImpl.deploy(DeployerImpl.java:105)
    at org.glassfish.maven.PluginUtil.doDeploy(PluginUtil.java:106)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:606)
    at org.glassfish.maven.AbstractDeployMojo.doDeploy(AbstractDeployMojo.java:239)
    at org.glassfish.maven.RunMojo.execute(RunMojo.java:68)
    at org.apache.maven.plugin.DefaultBuildPluginManager.executeMojo(DefaultBuildPluginManager.java:107)
    at org.apache.maven.lifecycle.internal.MojoExecutor.execute(MojoExecutor.java:209)
    at org.apache.maven.lifecycle.internal.MojoExecutor.execute(MojoExecutor.java:153)
    at org.apache.maven.lifecycle.internal.MojoExecutor.execute(MojoExecutor.java:145)
    at org.apache.maven.lifecycle.internal.LifecycleModuleBuilder.buildProject(LifecycleModuleBuilder.java:84)
    at org.apache.maven.lifecycle.internal.LifecycleModuleBuilder.buildProject(LifecycleModuleBuilder.java:59)
    at org.apache.maven.lifecycle.internal.LifecycleStarter.singleThreadedBuild(LifecycleStarter.java:183)
    at org.apache.maven.lifecycle.internal.LifecycleStarter.execute(LifecycleStarter.java:161)
    at org.apache.maven.DefaultMaven.doExecute(DefaultMaven.java:319)
    at org.apache.maven.DefaultMaven.execute(DefaultMaven.java:156)
    at org.apache.maven.cli.MavenCli.execute(MavenCli.java:534)
    at org.apache.maven.cli.MavenCli.doMain(MavenCli.java:196)
    at org.apache.maven.cli.MavenCli.main(MavenCli.java:141)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:606)
    at org.codehaus.plexus.classworlds.launcher.Launcher.launchEnhanced(Launcher.java:290)
    at org.codehaus.plexus.classworlds.launcher.Launcher.launch(Launcher.java:230)
    at org.codehaus.plexus.classworlds.launcher.Launcher.mainWithExitCode(Launcher.java:409)
    at org.codehaus.plexus.classworlds.launcher.Launcher.main(Launcher.java:352)
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'entityManagerFactory' defined in class path resource [com/marc/embeddedglassfish/config/PersistenceContext.class]: Invocation of init method failed; nested exception is java.lang.reflect.UndeclaredThrowableException
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1486)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:524)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:461)
    at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:295)
    at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:223)
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:292)
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:194)
    at org.springframework.context.support.AbstractApplicationContext.getBean(AbstractApplicationContext.java:1117)
    at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:922)
    at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:479)
    at org.springframework.web.context.ContextLoader.configureAndRefreshWebApplicationContext(ContextLoader.java:383)
    at org.springframework.web.context.ContextLoader.initWebApplicationContext(ContextLoader.java:283)
    at org.springframework.web.context.ContextLoaderListener.contextInitialized(ContextLoaderListener.java:112)
    at org.apache.catalina.core.StandardContext.contextListenerStart(StandardContext.java:4750)
    at com.sun.enterprise.web.WebModule.contextListenerStart(WebModule.java:550)
    at org.apache.catalina.core.StandardContext.start(StandardContext.java:5366)
    ... 49 more
Caused by: java.lang.reflect.UndeclaredThrowableException
    at com.sun.proxy.$Proxy147.addTransformer(Unknown Source)
    at org.eclipse.persistence.jpa.PersistenceProvider.createContainerEntityManagerFactory(PersistenceProvider.java:231)
    at org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean.createNativeEntityManagerFactory(LocalContainerEntityManagerFactoryBean.java:287)
    at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.afterPropertiesSet(AbstractEntityManagerFactoryBean.java:310)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1545)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1483)
    ... 64 more
Caused by: java.lang.reflect.InvocationTargetException
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:606)
    at org.springframework.orm.jpa.persistenceunit.DefaultPersistenceUnitManager$Jpa2PersistenceUnitInfoDecorator.invoke(DefaultPersistenceUnitManager.java:617)
    ... 70 more
Caused by: java.lang.IllegalStateException: Cannot apply class transformer without LoadTimeWeaver specified
    at org.springframework.orm.jpa.persistenceunit.SpringPersistenceUnitInfo.addTransformer(SpringPersistenceUnitInfo.java:109)
    ... 75 more

PersistenceContext.java

package com.marc.embeddedglassfish.config;

import java.util.Properties;

import javax.persistence.EntityManagerFactory;
import javax.sql.DataSource;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.env.Environment;
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
import org.springframework.jdbc.datasource.lookup.JndiDataSourceLookup;
import org.springframework.orm.jpa.JpaTransactionManager;
import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean;
import org.springframework.orm.jpa.vendor.Database;
import org.springframework.orm.jpa.vendor.EclipseLinkJpaVendorAdapter;
import org.springframework.transaction.annotation.EnableTransactionManagement;
import org.springframework.transaction.support.AbstractPlatformTransactionManager;

import com.marc.springmvc3.dao.PersonDAO;

@Configuration
@EnableTransactionManagement
@EnableJpaRepositories(basePackages = {"com.marc.springmvc3.repositories"})
public class PersistenceContext {
         /*    glassfish requires "java:app/"

    Deployment Descriptor. An application-scoped resource is defined in the glassfish-resources.xml deployment descriptor file. 
    This file is placed in the META-INF directory of the module or application archive. For web applications or modules, 
    this file is placed in the WEB-INF directory. If any submodule archives of an enterprise application archive have their 
    own glassfish-resources.xml files, the resource definitions are scoped to those modules only. For more information about 
    the glassfish-resources.xml file, see Appendix B, GlassFish Server Deployment Descriptor Files and Appendix C, Elements of the 
    GlassFish Server Deployment Descriptors.

    Naming. Application-scoped resource JNDI names begin with java:app or java:module. If one of these prefixes is not specified 
    in the JNDI name, it is added. For example, application-scoped databases have JNDI names in the following format: 
    java:app/jdbc/DataSourceName or java:module/jdbc/DataSourceName. This is in accordance with the naming scopes introduced 
    in the Java EE 6 Specification. 

    http://docs.oracle.com/cd/E18930_01/html/821-2417/giydj.html
    oracle glassfish application deployment guide 
   */

    @Bean
    public DataSource dataSource() {
        final JndiDataSourceLookup dsLookup = new JndiDataSourceLookup();
        dsLookup.setResourceRef(true);
        DataSource dataSource = dsLookup.getDataSource("java:app/jdbc/TestDB");
        return dataSource;
    }

    @Bean
    public PersonDAO personDao() {
        PersonDAO personDao = new PersonDAO();
        personDao.setDataSource(dataSource());
      return personDao;
    }

    @Bean
    public AbstractPlatformTransactionManager transactionManager() {
        return new JpaTransactionManager(entityManagerFactory());
    }

    @Bean
    public DataSource dataSourceForEntityManager() {
        final JndiDataSourceLookup dsLookup = new JndiDataSourceLookup();
        dsLookup.setResourceRef(true);
        // "jdbc/__TimerPool" is defined by default in embedded glassfish
        DataSource dataSource = dsLookup.getDataSource("jdbc/__TimerPool");
        return dataSource;
    }

    @Bean
    public EntityManagerFactory entityManagerFactory() {

        final LocalContainerEntityManagerFactoryBean entityManagerFactoryBean = new LocalContainerEntityManagerFactoryBean();
        EclipseLinkJpaVendorAdapter vendor = new EclipseLinkJpaVendorAdapter();
        vendor.setDatabase(Database.DERBY);
        vendor.setGenerateDdl(true);
        vendor.setShowSql(true);
        entityManagerFactoryBean.setJpaVendorAdapter(vendor);
        entityManagerFactoryBean.setJtaDataSource(dataSourceForEntityManager());
        entityManagerFactoryBean.setPackagesToScan(new String[] { "com.marc.springmvc3.model" });
       final Properties props = new Properties();
        props.setProperty("javax.persistence.jdbc.driver", "org.apache.derby.jdbc.EmbeddedDriver");
        props.setProperty("eclipselink.target-database", "DERBY");
        props.setProperty("eclipselink.ddl-generation", "drop-and-create-table");
        props.setProperty("eclipselink.logging.level.sql", "FINEST");
        props.setProperty("eclipselink.logging.parameters", "true");

        entityManagerFactoryBean.setJpaProperties(props);
        entityManagerFactoryBean.afterPropertiesSet();
        return entityManagerFactoryBean.getObject();
    }

}

PersonService.java

package com.marc.springmvc3.service;

import java.util.List;

import javax.inject.Inject;

import org.springframework.stereotype.Service;

import com.marc.springmvc3.model.Person;
import com.marc.springmvc3.repositories.PersonRepository;

@Service
public class PersonService {
    @Inject 
    private PersonRepository repository;

    @Inject
    private List<Person> persons;
    public List<Person> getAllPersons() {
        Person person = new Person();
        person.setFirstName("Lucky");
        person.setName("Luke");

        repository.save(person);
        person.setFirstName("");
        person.setName("");
        Person dbPerson = repository.findOne(person.getId());
        persons.add(dbPerson);
        return persons;
    }
}

PersonRepository.java

package com.marc.springmvc3.repositories;

import org.springframework.data.jpa.repository.JpaRepository;

import com.marc.springmvc3.model.Person;

public interface PersonRepository extends JpaRepository<Person, Integer> {

}

Initiliazer

package com.marc.embeddedglassfish.initializer;

import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.ServletRegistration;

import org.springframework.web.WebApplicationInitializer;
import org.springframework.web.context.ContextLoaderListener;
import org.springframework.web.context.WebApplicationContext;
import org.springframework.web.context.support.AnnotationConfigWebApplicationContext;
import org.springframework.web.servlet.DispatcherServlet;

public class EmbeddedGlassfishInitializer implements WebApplicationInitializer {
    private static final String DISPATCHER_SERVLET_NAME = "dispatcher";
    private static final String DISPATCHER_SERVLET_MAPPING = "/";

    @Override
    public void onStartup(ServletContext servletContext) throws ServletException {
        WebApplicationContext context = getContext();
        servletContext.addListener(new ContextLoaderListener(context));
        ServletRegistration.Dynamic dispatcher = servletContext.addServlet("DispatcherServlet", new DispatcherServlet(context));
        dispatcher.setLoadOnStartup(1);
        dispatcher.addMapping("/");
    }

    private AnnotationConfigWebApplicationContext getContext() {
        AnnotationConfigWebApplicationContext context = new AnnotationConfigWebApplicationContext();
        context.setConfigLocation("com.marc.embeddedglassfish.config");
        return context;
    }
}

2 个答案:

答案 0 :(得分:3)

我解决了它

堆栈跟踪的有趣部分在最后: 引起:java.lang.IllegalStateException:未指定LoadTimeWeaver时无法应用类转换器

这里的解释帮助了我:EclipseLinkJpaVendorAdapter instead of HibernateJpaVendorAdapter issue

我仍然不知道如何在基于Java的应用程序上下文配置中从Glassfish获取EntitManagerFactory作为JNDI。有什么想法吗?

答案 1 :(得分:0)

应该是:

@Bean
public FactoryBean<EntityManagerFactory> entityManagerFactory() {
    ...

    entityManagerFactoryBean.setJpaProperties(props);
    return entityManagerFactoryBean;    
}

@Bean
public PlatformTransactionManager transactionManager(EntityManagerFactory entityManagerFactory) {
        return new JpaTransactionManager(entityManagerFactory);
    }

不建议直接从代码中实例化任何FactoryBean:需要依赖Spring contaier

要使用FactoryBean结果,必须遵循参数injection策略。