JavaConfig - Spring JPA Hibernate - @EnableTransactionManagement

Posted

技术标签:

【中文标题】JavaConfig - Spring JPA Hibernate - @EnableTransactionManagement【英文标题】: 【发布时间】:2016-03-09 13:41:50 【问题描述】:

我正在尝试使用 Spring4、Hibernate 和带有 JavaConfig 和 Tomcat8-Server 的 HSQLDB-Database 设置一个演示项目。我遵循了几个教程,但都以相同的异常告终。

这是我的配置:

@Configuration
@EnableTransactionManagement
@Slf4j
public class DatasourceConfig


@Bean
DataSource dataSource()

    DataSource dataSource = null;
    JndiTemplate jndi = new JndiTemplate();
    try 
    
        dataSource = (DataSource) jndi.lookup("java:comp/env/jdbc/testdb");
     
    catch (NamingException e) 
    
        log.error(e.toString());
    
    return dataSource;


  @Bean
  public LocalContainerEntityManagerFactoryBean entityManagerFactoryBean() 
  
      LocalContainerEntityManagerFactoryBean entityManagerFactoryBean = new LocalContainerEntityManagerFactoryBean();
      entityManagerFactoryBean.setDataSource(dataSource());
      entityManagerFactoryBean.setPackagesToScan("packageNameWithModels");

      JpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter();
      entityManagerFactoryBean.setJpaVendorAdapter(vendorAdapter);
      entityManagerFactoryBean.setJpaProperties(hibProperties());

      return entityManagerFactoryBean;
  

   @Bean
   public PlatformTransactionManager transactionManager()
   
      JpaTransactionManager transactionManager = new JpaTransactionManager();
      transactionManager.setEntityManagerFactory(entityManagerFactoryBean().getObject());
      return transactionManager;
   



   @Bean
   public PersistenceExceptionTranslationPostProcessor exceptionTranslation()
      return new PersistenceExceptionTranslationPostProcessor();
   


  private Properties hibProperties() 
  
      Properties properties = new Properties();
      properties.put("hibernate.dialect", "org.hibernate.dialect.HSQLDialect");
      properties.put("hibernate.show_sql", "true");
      return properties;        
       


Maven 安装就像一个魅力,但是当我尝试启动 tomcat8-Server 时,我收到以下错误:

WARNUNG: Exception encountered during context initialization - cancelling refresh attempt: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'org.springframework.context.event.internalEventListenerProcessor': Initialization of bean failed; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'org.springframework.transaction.config.internalTransactionAdvisor' defined in class path resource [org/springframework/transaction/annotation/ProxyTransactionManagementConfiguration.class]: Bean instantiation via factory method failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.springframework.transaction.interceptor.BeanFactoryTransactionAttributeSourceAdvisor]: Factory method 'transactionAdvisor' threw exception; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'transactionInterceptor' defined in class path resource [org/springframework/transaction/annotation/ProxyTransactionManagementConfiguration.class]: Invocation of init method failed; nested exception is java.lang.IllegalArgumentException: Property 'transactionManager' is required
Mär 09, 2016 2:23:12 PM org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean destroy
INFORMATION: Closing JPA EntityManagerFactory for persistence unit 'default'
Mär 09, 2016 2:23:12 PM org.apache.catalina.core.ContainerBase startInternal
SCHWERWIEGEND: A child container failed during start
java.util.concurrent.ExecutionException: org.apache.catalina.LifecycleException: Failed to start component [StandardEngine[Catalina].StandardHost[localhost].StandardContext[/springmvc]]
    at java.util.concurrent.FutureTask.report(FutureTask.java:122)
    at java.util.concurrent.FutureTask.get(FutureTask.java:192)
    at org.apache.catalina.core.ContainerBase.startInternal(ContainerBase.java:916)
    at org.apache.catalina.core.StandardHost.startInternal(StandardHost.java:871)
    at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:150)
    at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1408)
    at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1398)
    at java.util.concurrent.FutureTask.run(FutureTask.java:266)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
    at java.lang.Thread.run(Thread.java:745)
Caused by: org.apache.catalina.LifecycleException: Failed to start component [StandardEngine[Catalina].StandardHost[localhost].StandardContext[/springmvc]]
    at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:154)
    ... 6 more
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'org.springframework.context.event.internalEventListenerProcessor': Initialization of bean failed; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'org.springframework.transaction.config.internalTransactionAdvisor' defined in class path resource [org/springframework/transaction/annotation/ProxyTransactionManagementConfiguration.class]: Bean instantiation via factory method failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.springframework.transaction.interceptor.BeanFactoryTransactionAttributeSourceAdvisor]: Factory method 'transactionAdvisor' threw exception; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'transactionInterceptor' defined in class path resource [org/springframework/transaction/annotation/ProxyTransactionManagementConfiguration.class]: Invocation of init method failed; nested exception is java.lang.IllegalArgumentException: Property 'transactionManager' is required
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:553)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:482)
    at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:306)
    at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230)
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:302)
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:197)
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:772)
    at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:839)
    at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:538)
    at ag.bpc.springmvc.config.WebapplicationInitializer.onStartup(WebapplicationInitializer.java:19)
    at org.springframework.web.SpringServletContainerInitializer.onStartup(SpringServletContainerInitializer.java:175)
    at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5244)
    at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:150)
    ... 6 more

据我了解,@EnableTransactionManagment-annotation 搜索事务管理器 bean,找到它但无法找到由代码设置的实体管理器:

transactionManager.setEntityManagerFactory(entityManagerFactoryBean().getObject());

也许有人可以帮助我? 提前致谢 皮特

【问题讨论】:

你用的是什么spring版本? 【参考方案1】:

不确定您的设置有什么问题。请尝试此设置。删除您的 entityManagerFactoryBeantransactionManagerhibProperties 方法。

@Bean
@Autowired
public EntityManagerFactory entityManagerFactory(DataSource dataSource) 
    HibernateJpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter();
    vendorAdapter.setGenerateDdl(false);

    LocalContainerEntityManagerFactoryBean factory = new LocalContainerEntityManagerFactoryBean();
    factory.setJpaVendorAdapter(vendorAdapter);
    factory.setPackagesToScan("com.company.project");
    factory.setDataSource(dataSource);

    Properties jpaProperties = new Properties();
    jpaProperties.put("hibernate.dialect", "org.hibernate.dialect.HSQLDialect");
    jpaProperties.put("hibernate.show_sql", true);
    factory.setJpaProperties(jpaProperties);

    factory.afterPropertiesSet();
    return factory.getObject();


@Bean
@Autowired
public PlatformTransactionManager transactionManager(EntityManagerFactory entityManagerFactory) 
    JpaTransactionManager jpaTransactionManager = new JpaTransactionManager(entityManagerFactory);
    return jpaTransactionManager;

【讨论】:

【参考方案2】:

我发现了问题,我在 pom.xml 中定义了一个过时的依赖项:

<dependency>
  <groupId>org.springframework</groupId>
  <artifactId>spring-dao</artifactId>
  <version>2.0.8</version>
</dependency>

删除此依赖项后,它就可以工作了。 无论如何,非常感谢您的帮助!

【讨论】:

以上是关于JavaConfig - Spring JPA Hibernate - @EnableTransactionManagement的主要内容,如果未能解决你的问题,请参考以下文章

Spring重温--Spring JavaConfig

Spring JavaConfig实例

Spring JavaConfig配置

spring_JavaConfig

Spring 使用javaconfig配置

180531-Spring中JavaConfig知识小结