簡體   English   中英

在Wildfly 9下運行Java配置的Spring應用程序時沒有事務

[英]No transactions when java-configured spring app is running under Wildfly 9

我們正在更新一個舊的Spring應用程序以使用java-config而不是XML。 該應用程序在單元測試期間運行良好,但是當在Wildfly下部署時,似乎事務處於非活動狀態,並且實體管理器從未關閉:盡管記錄器org.springframework.transaction ,我們也看不到插入/更新被發送到DB。和
org.springframework.orm.jpa設置為DEBUG,我們沒有事務開始/結束的痕跡。

我們使用Wildfly 9.0.2和Wildfly BOM(=> Hibernate 4.3.10)和Spring 4.3.7。 我們有兩個應用程序模塊(.war)和一個持久性模塊(.jar)在它們之間共享。

持久性模塊包含JpaConfig.java和DaoConfig.java配置類:

@Configuration
@EnableTransactionManagement(proxyTargetClass = true)
public class JpaConfig {

    @Bean(destroyMethod = "close")
    public EntityManagerFactory entityManagerFactory(DataSource datasource, JpaVendorAdapter jpaVendorAdapter) {
        LocalContainerEntityManagerFactoryBean entityManagerFactory = new LocalContainerEntityManagerFactoryBean();
        entityManagerFactory.setDataSource(datasource);
        entityManagerFactory.setJpaVendorAdapter(jpaVendorAdapter);
        entityManagerFactory.setJpaProperties(jpaProperties());
        entityManagerFactory.setJpaDialect(new HibernateJpaDialect());
        entityManagerFactory.setPackagesToScan("my.package.for.entities");
        entityManagerFactory.setPersistenceUnitName("my-pu");
        entityManagerFactory.afterPropertiesSet();
        return entityManagerFactory.getObject();
    }

    @Bean
    public PlatformTransactionManager transactionManager(EntityManagerFactory emf) {
        JpaTransactionManager transactionManager = new JpaTransactionManager();
        transactionManager.setEntityManagerFactory(emf);
        return transactionManager;
    }

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

    @Bean
    public JpaVendorAdapter jpaVendorAdapter() {
        HibernateJpaVendorAdapter adapter = new HibernateJpaVendorAdapter();
        adapter.setDatabase(Database.MYSQL);
        adapter.setGenerateDdl(false);
        adapter.setShowSql(LOG.isDebugEnabled());
        return adapter;
    }

    @Bean
    public DataSource dataSource() {
        return new JndiDataSourceLookup().getDataSource("java:/appDS");
    }

    protected Properties jpaProperties() {
        Properties props = new Properties();
        props.setProperty("hibernate.hibernate.dialect", MySQL5InnoDBDialect.class.getName());
        props.setProperty("hibernate.show_sql", LOG.isDebugEnabled() ? "true" : "false");
        props.setProperty("hibernate.format_sql", "false");
        return props;
    }
}
@Configuration
@ComponentScan("my.package.for.repositories")
@EnableTransactionManagement(proxyTargetClass = true)
public class DaoConfig {
 ...
}

我們一直在嘗試上述方法的多種變體(直接返回LocalContainerEntityManagerFactoryBean而不是調用afterPropertiesSet + getObject並返回EntityManager,無論是否在META-INF中使用persistence.xml,帶有和不帶有“ Dependencies”清單條目,冗余都較少配置類之間,...),但沒有成功。

這兩個WAR都有自己的配置類,所有這些配置類均導入JpaConfig.java並以@EnableTransactionManagement進行注釋,例如:

@Configuration
@Import({ SecurityConfig.class, ServicesConfig.class, ControllerConfig.java, JpaConfig.class, DaoConfig.class })
public class RootConfig {
  ...
}
@Configuration
@EnableWebMvc
@EnableTransactionManagement(proxyTargetClass = true)
@ComponentScan("com.my.controller")
public class ControllerConfig extends WebMvcConfigurerAdapter {
  ...
}
@Configuration
@EnableWebSecurity
@PropertySource("classpath:security.properties")
public class SecurityConfig extends WebSecurityConfigurerAdapter {
...
}
@Configuration
@EnableAspectJAutoProxy
@EnableGlobalMethodSecurity(prePostEnabled = true)
@ComponentScan("com.my.services")
@Import(DaoConfig.class)
...
}

所有控制器都使用@Transactional進行注釋,因此我希望Spring每當調用端點時都會創建一個新事務,並在方法返回時刷新並關閉EM +提交事務。 但這不會發生:這是我們的日志的一部分:

INFO  [RequestProcessingTimeInterceptor] [Start call] POST http://server/web/api/rest/catalog/2
INFO  [stdout] Hibernate: select .... from CATALOG catalog0_ where catalog0_.id=?
INFO  [CatalogServiceImpl] Updating catalog #2...
INFO  [CatalogServiceImpl] Catalog #2 updated !
INFO  [RequestProcessingTimeInterceptor] [Call took 23ms] POST http://server/web/api/rest/catalog/2

某處應該有一條更新語句。 我是否缺少明顯的東西?

我們終於解決了這個問題。

實際上,以上配置是正確的。 事務已正確創建。 未將更改刷新到數據庫的原因是某人(錯誤地)向實體添加了@Immutable注釋。

@Immutable實體更新時,Hibernate不會記錄任何警告,也不會拋出警告。 因此,如果您遇到相同的問題,請檢查該實體上的注釋。

如果有任何Hibernate維護者找到了這個答案:最好在更新不可變實體時默認記錄一個警告。 這將使發現此類編碼錯誤更加容易。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM