2017-11-07 1 views
0

Wir aktualisieren eine alte Spring-Anwendung, um anstelle von XML java-config zu verwenden. Die Anwendung läuft während Komponententests einwandfrei, aber wenn sie unter Wildfly bereitgestellt wird, scheinen die Transaktionen inaktiv zu sein und der Entity Manager wird nie geschlossen: Es werden keine Einfügungen/Aktualisierungen an die Datenbank gesendet, und trotz der Logger org.springframework.transaction und
org.springframework.orm.jpa sind auf DEBUG gesetzt, wir bekommen keine Spuren von Transaktionsbeginn/-ende.Keine Transaktionen, wenn die java-konfigurierte Spring-App unter Wildfly ausgeführt wird 9

Wir verwenden Wildfly 9.0.2 mit Wildfly BOM (=> Hibernate 4.3.10) und Spring 4.3.7. Wir haben zwei Anwendungsmodule (.war) und ein Persistenzmodul (.jar) zwischen ihnen.

Die Persistenz-Modul hält die JpaConfig.java und DaoConfig.java Klassen-Konfiguration:

@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 { 
... 
} 

Wir haben mehrere Variationen der obigen Versuch (Rückkehr LocalContainerEntityManagerFactoryBean direkt statt Aufruf afterPropertiesSet + getObject und Rückgabe des EntityManager , mit und ohne persistence.xml in META-INF, mit und ohne Manifesteintrag "Dependencies", weniger redundant zwischen Configuration-Klassen, ...), ohne Erfolg.

Beiden WARs haben ihre eigenen Konfigurationsklassen, von denen alle JpaConfig.java importieren und mit @EnableTransactionManagement kommentiert, wie zum Beispiel:

@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) 
... 
} 

Alle Regler sind mit @Transactional kommentiert, also würde ich Frühling erwarten zu schaffen eine neue Transaktion, sobald ein Endpunkt aufgerufen wird, und bündig und schließen Sie die EM + Commit die Transaktion, wenn die Methoden zurückkehren. Aber das passiert nicht: Hier ist ein Auszug unserer Protokolle:

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 

Es sollte irgendwo eine Update-Anweisung sein. Fehle ich etwas offensichtlich?

Antwort

0

Wir haben dieses Problem endlich gelöst.

Eigentlich ist die obige Konfiguration korrekt. Transaktionen werden ordnungsgemäß erstellt. Der Grund, warum die Änderungen nicht in die DB geleert wurden, ist, dass jemand versehentlich eine Annotation zu der Entität hinzugefügt hat.

Hibernate protokolliert keine Warnung und wird nicht ausgelöst, wenn eine Entität aktualisiert wird. Falls Sie das gleiche Problem haben ... überprüfen Sie die Anmerkungen zu der Entität.

Falls ein Hibernate-Betreuer diese Antwort findet: Es wäre schön, wenn Hibernate standardmäßig eine Warnung protokolliert, wenn eine unveränderliche Entität aktualisiert wird. Das würde es einfacher machen, solche Codierungsfehler zu erkennen.

Verwandte Themen