2016-11-24 73 views
2

我有這種奇怪的情況,當在測試環境中一切正常時,但是當部署在WildFly上時,entityManager由於某種原因找不到事務。 我已經檢查過bean是否創建了兩次 - 一次是在mvc中,一次是在覈心上下文中 - 但是trace只出現一次。 在StackOverflow上嘗試了幾乎所有其他修復程序,但問題(與我希望EntityManager保存的數據不同)仍然存在。在Spring + Hibernate + JPA設置中沒有創建事務

也許你能在我的配置中發現一些我找不到的錯誤?

休眠的java配置(數據源是在另一模塊初始化,切換到評論DS什麼都不做):

@Configuration 
@EnableTransactionManagement(mode = AdviceMode.ASPECTJ) 
@EnableJpaRepositories(
     entityManagerFactoryRef = "user.management.entityManagerFactory", 
     transactionManagerRef = "user.management.transactionManager") 
public class HibernateConfiguration { 
    private static final String PROPERTY_NAME_DATABASE_DRIVER = "org.postgresql.Driver"; 
    private static final String PROPERTY_NAME_DATABASE_PASSWORD = ""; 
    private static final String PROPERTY_NAME_DATABASE_URL = "jdbc:postgresql://localhost:5432/postgres"; 
    private static final String PROPERTY_NAME_DATABASE_USERNAME = "postgres"; 

    private static final String PROPERTY_NAME_HIBERNATE_DIALECT = "hibernate.dialect"; 
    private static final String PROPERTY_NAME_HIBERNATE_SHOW_SQL = "hibernate.show_sql"; 
    private static final String PROPERTY_NAME_ENTITYMANAGER_PACKAGES_TO_SCAN = "entitymanager.packages.to.scan"; 

    @Resource 
    private Environment env; 

    @Autowired 
    @Bean(name = "user.management.jpaDialect") 
    HibernateJpaDialect getDialect() { 
     return new HibernateJpaDialect(); 
    } 

    @Autowired 
    @Bean(name = "user.management.jpaVendorAdapter") 
    HibernateJpaVendorAdapter getJpaVendorAdapter() { 
     HibernateJpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter(); 
     vendorAdapter.setDatabase(Database.HSQL); 
     vendorAdapter.setDatabasePlatform("org.hibernate.dialect.HSQLDialect"); 
     vendorAdapter.setGenerateDdl(false); 
     return vendorAdapter; 
    } 

    @Autowired 
    @Bean(name = "user.management.impl.repository.util.DbUtil") 
    DbUtil getDbUtil(
      @Qualifier("DataSource") 
        DataSource dataSource 
    ) { 
     DbUtil dbUtil = new DbUtil(dataSource); 
     return dbUtil; 
    } 

    @Autowired 
    @Bean(name = "hibernate5AnnotatedSessionFactory") 
    LocalSessionFactoryBuilder getLocalSessionFactoryBean(
      @Qualifier("DataSource") 
        DataSource dataSource 
    ) { 
     LocalSessionFactoryBuilder localSessionFactoryBean = 
       new LocalSessionFactoryBuilder(dataSource); 
     localSessionFactoryBean.scanPackages(
       "user.management.impl.repository.pojo" 
     ); 
     localSessionFactoryBean.addProperties(getHibernateProperties()); 
     localSessionFactoryBean.buildSessionFactory(); 

     return localSessionFactoryBean; 
    } 

    private Properties getHibernateProperties() { 
     Properties properties = new Properties(); 
     properties.put("hibernate.show_sql", "false"); 
     properties.put("hibernate.current_session_context_class", "thread"); 
     properties.put("hibernate.dialect", "org.hibernate.dialect.HSQLDialect"); 
     return properties; 
    } 

    /*@Autowired 
    @Bean(name = "user.management.dataSource") 
    public DataSource getPooledDataSource() { 
     DriverManagerDataSource dataSource = new DriverManagerDataSource(); 
     dataSource.setDriverClassName(PROPERTY_NAME_DATABASE_DRIVER); 
     dataSource.setUrl(PROPERTY_NAME_DATABASE_URL); 
     dataSource.setUsername(PROPERTY_NAME_DATABASE_USERNAME); 
     dataSource.setPassword(PROPERTY_NAME_DATABASE_PASSWORD); 
     return dataSource; 
    }*/ 

    @Autowired 
    @Bean(name = "user.management.entityManagerFactory") 
    public LocalContainerEntityManagerFactoryBean getEntityManagerFactory(
      @Qualifier("DataSource") 
        DataSource dataSource 
    ) { 
     System.out.println("getEntityManagerFactory()"); 

     LocalContainerEntityManagerFactoryBean theEntityManager = new LocalContainerEntityManagerFactoryBean(); 
     theEntityManager.setPersistenceXmlLocation("classpath:META-INF/persistence.xml"); 
     theEntityManager.setPersistenceUnitName("umPersistenceUnit"); 
     theEntityManager.setDataSource(dataSource); 
     theEntityManager.setPackagesToScan(
       "user.management.impl.repository.pojo", 
     ); 
     theEntityManager.setJpaVendorAdapter(getJpaVendorAdapter()); 
     theEntityManager.setJpaDialect(getJpaDialect()); 
     theEntityManager.afterPropertiesSet(); 

     return theEntityManager; 
    } 

    @Autowired 
    @Bean(name = "user.management.jpaDialect") 
    public JpaDialect getJpaDialect() { 
     return new HibernateJpaDialect(); 
    } 

    @Autowired 
    @Bean(name = "user.management.transactionManager") 
    public JpaTransactionManager getTransactionManager(
      @Qualifier("user.management.entityManagerFactory") 
        EntityManagerFactory entityManagerFactory, 
      @Qualifier("DataSource") 
        DataSource dataSource 
    ) { 
     JpaTransactionManager jpaTranstactionManager = 
       new JpaTransactionManager(entityManagerFactory); 
     jpaTranstactionManager.setDataSource(dataSource); 
     jpaTranstactionManager.setJpaDialect(getJpaDialect()); 
     jpaTranstactionManager.setEntityManagerFactory(entityManagerFactory); 
     jpaTranstactionManager.afterPropertiesSet(); 

     return jpaTranstactionManager; 
    } 

    //DAO Classes 

    @Autowired 
    @Bean(name = "user.management.userRepository") 
    public UserRepository getUserDao(
      @Qualifier("cacheManager") 
        CacheManager cacheManager) { 
     return new UserDaoImpl(getIdGenerator(), cacheManager); 
    } 

    @Autowired 
    @Bean(name = "user.management.groupDao") 
    public GroupRepository getGroupDao() { 
     return new GroupDaoImpl(getIdGenerator()); 
    } 

    @Autowired 
    @Bean(name = "user.management.roleDao") 
    public RoleRepository getRoleDao() { 
     return new RoleDaoImpl(getIdGenerator()); 
    } 

    @Autowired 
    @Bean(name = "user.management.profileDao") 
    public UserProfileRepository getProfileRepository() { 
     return new UserProfileDaoImpl(getIdGenerator()); 
    } 

    @Autowired 
    @Bean(name = "user.management.impl.service.idgenerator.IdGenerator") 
    public IdGenerator getIdGenerator() { 
     return new IdGenerator(); 
    } 

    @Autowired 
    @Bean(name = "user.management.AuthenticatorRepositoryDAO") 
    public AuthenticatorRepository getAuthenticationRepository() { 
     return new AuthenticatorRepositoryDAO(); 
    } 

    @Autowired 
    @Bean(name = "user.management.dobLdapSourceRepository") 
    public LdapSourceRepository getLdapSourceRepository() { 
     return new LdapSourceRepositoryImpl(); 
    } 

    @Autowired 
    @Bean(name = "user.management.dobOpenIdAuthenticationProviderRepository") 
    public OpenIdAuthenticationProviderRepository getOpenIdAuthenticationProviderRepository() { 
     return new OpenIdAuthenticationProviderRepositoryDAO(); 
    } 
} 

服務的java配置

@Configuration 
public class UserManagementConfiguration { 
    @Autowired 
    @Bean(name = "user.management.services.UserService") 
    public UserService getUserService(...) { 
     return new UserServiceImpl(...); 
    } 
} 

DAO

@Transactional(propagation = Propagation.REQUIRED) 
public class UserDao implements UserRepository { 

    public UserDao(...) {} 

    @PersistenceContext(unitName = "umPersistenceUnit") 
    private EntityManager entityManager; 

    @Override 
    @Transactional(propagation = Propagation.REQUIRED) 
    public void persistUser(@Nonnull MutableUser user) { 
     entityManager.persist(user); 
    } 
} 

服務

public class UserServiceImpl implements UserService { 

    public UserServiceImpl(...); 
    } 


    @Override 
    @Transactional 
    public void persistUser(@Nonnull User user) { 
     userDAO.persistUser(mutableUser); 
    } 
} 

的persistence.xml

<?xml version="1.0" encoding="UTF-8"?> 
<persistence xmlns="http://java.sun.com/xml/ns/persistence" 
      version="1.0"> 
    <persistence-unit name="umPersistenceUnit"> 
     <!-- Forces Hibernate to work with old-style annotations --> 
     <properties> 
      <property name="hibernate.id.new_generator_mappings" value="false"></property> 
     </properties> 
     <provider>org.hibernate.ejb.HibernatePersistence</provider> 

     <class>user.management.impl.repository.pojo.User</class> 
    </persistence-unit> 
</persistence> 

彈簧的config.xml

<beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
     xmlns:context="http://www.springframework.org/schema/context" 
     xmlns="http://www.springframework.org/schema/beans" 
     xmlns:tx="http://www.springframework.org/schema/tx" 
     xsi:schemaLocation="http://www.springframework.org/schema/beans 
      http://www.springframework.org/schema/beans/spring-beans-3.0.xsd 
      http://www.springframework.org/schema/context 
      http://www.springframework.org/schema/context/spring-context-3.0.xsd 
      http://www.springframework.org/schema/tx 
      http://www.springframework.org/schema/tx/spring-tx.xsd"> 

    <context:annotation-config/> 

    <tx:annotation-driven transaction-manager="user.management.transactionManager"/> 

    <bean class="user.management.config.UserManagementConfiguration"/> 
    <bean class="user.management.config.HibernateConfiguration"/> 

    </bean> 
</beans> 

測試配置是相同的,只是使用了不同的dataSourcejdbc.driver連接到內存中的H 2。 我已經嘗試過:

  1. DaoService類使用<tx:annotation-driven>並指向正確的transactionManagerFactory

  2. 刪除transaction-type="RESOURCE_LOCAL"persistence.xml

  3. 添加@Transactional到具體的方法。

  4. 檢查發現entityManagerFactory僅在服務器啓動

  5. 調試的服務器,看看一些其他的EntityManager被稱爲加載一次。我可以在其屬性中清楚地看到我的持久性單元和限定符。

  6. 當我試着谷歌關於這個問題時可能會彈出一些其他小的修復。

當我當entitymanager.flush()加入成爲javax.persistence.TransactionRequiredException: no transaction is in progress

+0

主要的問題是,你已經指定了'hibernate.current_session_context_class'這個事實來破壞正確的集成。另一件事是你爲什麼要爲相同的實體配置一個'SessioNFactory'和'EntityManagerFactory'? –

+0

@ M.Deinum'hibernate.current_session_context_class'確實可能會破壞一些東西,我會試着去除它,看看會發生什麼。至於'SessionFactory' +'EntityManagerFactory',我試過刪除'SessionFactory',但它導致了一個不同的問題 - (https://forum.hibernate.org/viewtopic.php?f=1&t=1043771&p=2490801 ) –

+0

這仍然不是很清楚,爲什麼你有兩個,尤其是因爲你似乎只使用JPA ... –

回答

1

提供transaction-type="JTA"明確persistence.xml中固定的問題展開像貼在這裏,我可以看到日誌等沒有錯誤代碼,實體是堅持數據庫成功。

相關問題