也许这种情况太常见但仍然存在。
我有一个小测试项目,我正在测试所有JPA的东西。我几乎在任何地方使用Spring Data和JPA存储库都可以正常工作。但现在我试图让我的服务来保存实体。该服务看起来像这样:
@Service
public class SomeServiceImpl implements SomeService {
@Autowired
private EntityManagerFactory entityManagerFactory;
public SomeServiceImpl(EntityManagerFactory entityManagerFactory) {
this.entityManagerFactory = entityManagerFactory;
}
@Override
@Transactional
public SomeEntity save(SomeEntity someEntity) {
EntityManager entityManager = entityManagerFactory.createEntityManager();
entityManager.persist(someEntity);
return someEntity;
}
持久性配置看起来像这样(我故意复制和粘贴整个配置。也许它会帮助你重现错误):
@Configuration
@EnableTransactionManagement
@EnableJpaRepositories
@PropertySource({"classpath:conf/application.properties"})
public class PersistenceConfig {
@Autowired
private Environment environment;
@Bean
public DataSource dataSource() throws SQLException {
PoolDataSourceImpl dataSource = new PoolDataSourceImpl();
dataSource.setConnectionFactoryClassName(environment.getRequiredProperty("db.driverClassName"));
dataSource.setURL(environment.getRequiredProperty("db.url"));
dataSource.setUser(environment.getRequiredProperty("db.username"));
dataSource.setPassword(environment.getRequiredProperty("db.password"));
dataSource.setFastConnectionFailoverEnabled(
Boolean.valueOf(environment.getRequiredProperty("db.fast.connect.failover.enabled")));
dataSource.setValidateConnectionOnBorrow(true);
dataSource.setSQLForValidateConnection("SELECT SYSDATE FROM DUAL");
dataSource.setONSConfiguration(environment.getRequiredProperty("db.ons.config"));
dataSource.setInitialPoolSize(Integer.valueOf(environment.getRequiredProperty("db.initial.pool.size")));
dataSource.setMinPoolSize(Integer.valueOf(environment.getRequiredProperty("db.min.pool.size")));
dataSource.setMaxPoolSize(Integer.valueOf(environment.getRequiredProperty("db.max.pool.size")));
dataSource.setAbandonedConnectionTimeout(0);
dataSource.setInactiveConnectionTimeout(60 * 25);
dataSource.setTimeToLiveConnectionTimeout(0);
dataSource.setMaxConnectionReuseTime(60 * 30L);
return dataSource;
}
private Properties hibernateProperties() {
Properties properties = new Properties();
properties.setProperty("hibernate.dialect", environment.getRequiredProperty("hibernate.dialect"));
properties.setProperty("hibernate.show_sql", environment.getRequiredProperty("hibernate.show_sql"));
properties.setProperty("hibernate.format_sql", environment.getRequiredProperty("hibernate.format_sql"));
properties.setProperty("hibernate.hbm2ddl.auto", environment.getRequiredProperty("hibernate.hbm2ddl.auto"));
return properties;
}
@Bean
public LocalContainerEntityManagerFactoryBean entityManagerFactory(@Autowired DataSource dataSource) {
LocalContainerEntityManagerFactoryBean entityManagerFactory = new LocalContainerEntityManagerFactoryBean();
entityManagerFactory.setDataSource(dataSource);
entityManagerFactory.setPackagesToScan("com.dropbinc.learning.jpa.model");
JpaVendorAdapter jpaVendorAdapter = new HibernateJpaVendorAdapter();
entityManagerFactory.setJpaVendorAdapter(jpaVendorAdapter);
Map jpaProperties = new HashMap();
jpaProperties.put("javax.persistence.schema-generation.database.action", "drop-and-create");
entityManagerFactory.setJpaPropertyMap(jpaProperties);
entityManagerFactory.setJpaProperties(hibernateProperties());
return entityManagerFactory;
}
@Bean
public PlatformTransactionManager transactionManager(@Autowired EntityManagerFactory entityManagerFactory) {
JpaTransactionManager transactionManager = new JpaTransactionManager();
transactionManager.setEntityManagerFactory(entityManagerFactory);
return transactionManager;
}
@Bean
public PersistenceExceptionTranslationPostProcessor exceptionTranslation() {
return new PersistenceExceptionTranslationPostProcessor();
}
}
还有一个我计划配置应用程序的其余部分(放在同一个包中):
@Configuration
@ComponentScan(basePackages = "com.dropbinc.learning.jpa")
public class AppConfig {
}
我试图调试Spring但是我无法检测到JPA存储库的事务行为与我的服务之间的区别。我看到交易已经创建甚至提交。但是在JPA存储库的情况下它被保存了,而在我的服务实现中它确实生成了id,但实体并没有出现在数据库中。
我在测试中运行所有内容,通过接口自动启动服务:
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = { AppConfig.class, PersistenceConfig.class })
public class AllTheTests {
@Autowired
SomeService someService;
...
}
非常感谢您的任何建议!
编辑添加entityManager.flush()
来电会产生nested exception is javax.persistence.TransactionRequiredException: no transaction is in progress
。