繁体   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