我有這種奇怪的情況,當在測試環境中一切正常時,但是當部署在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>
測試配置是相同的,只是使用了不同的dataSource
和jdbc.driver
連接到內存中的H 2。 我已經嘗試過:
在
Dao
和Service
類使用<tx:annotation-driven>
並指向正確的transactionManagerFactory
刪除
transaction-type="RESOURCE_LOCAL"
從persistence.xml
添加
@Transactional
到具體的方法。檢查發現
entityManagerFactory
僅在服務器啓動調試的服務器,看看一些其他的EntityManager被稱爲加載一次。我可以在其屬性中清楚地看到我的持久性單元和限定符。
當我試着谷歌關於這個問題時可能會彈出一些其他小的修復。
當我當entitymanager.flush()
加入成爲javax.persistence.TransactionRequiredException: no transaction is in progress
主要的問題是,你已經指定了'hibernate.current_session_context_class'這個事實來破壞正確的集成。另一件事是你爲什麼要爲相同的實體配置一個'SessioNFactory'和'EntityManagerFactory'? –
@ M.Deinum'hibernate.current_session_context_class'確實可能會破壞一些東西,我會試着去除它,看看會發生什麼。至於'SessionFactory' +'EntityManagerFactory',我試過刪除'SessionFactory',但它導致了一個不同的問題 - (https://forum.hibernate.org/viewtopic.php?f=1&t=1043771&p=2490801 ) –
這仍然不是很清楚,爲什麼你有兩個,尤其是因爲你似乎只使用JPA ... –