我有这种奇怪的情况,当在测试环境中一切正常时,但是当部署在WildFly上时,entityManager由于某种原因找不到事务。 我已经检查了bean是否创建了两次 - 一次是在mvc中,一次是在核心上下文中 - 但是trace只出现一次。 在StackOverflow上尝试了几乎所有其他修复,但问题(与我希望EntityManager保存的数据不同)仍然存在。
也许你能在我的配置中发现一些我找不到的错误?
Hibernate java config(DataSource在另一个模块中初始化,切换到注释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>
Spring 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
连接到内存中的h2。
我已经尝试过了:
使用<tx:annotation-driven>
并指向正确的transactionManagerFactory
从transaction-type="RESOURCE_LOCAL"
persistence.xml
将@Transactional
添加到Dao
和Service
类中的特定方法。
检查entityManagerFactory
仅在服务器启动时加载一次
调试服务器以查看是否调用了其他一些entityManager。我可以在其属性中清楚地看到我的持久性单元和限定符。
当我试图谷歌解决这个问题时,可能会出现一些其他的小修正。
当我部署像此处发布的代码时,我可以看到日志中没有错误等。添加entitymanager.flush()
后,它变为javax.persistence.TransactionRequiredException: no transaction is in progress
答案 0 :(得分:1)
为persistence.xml提供transaction-type="JTA"
明确修复了问题,实体正在成功地持久保存到数据库。