Java Spring JPA:没有正在进行的事务
我在Spring应用程序中持久化实体时遇到问题。只需执行Java Spring JPA:没有正在进行的事务,java,spring,spring-mvc,jpa,Java,Spring,Spring Mvc,Jpa,我在Spring应用程序中持久化实体时遇到问题。只需执行em.merge()即可完成,但不会更新数据库,尝试em.flush()会导致此异常: 2015-12-19 18:01:40调试调度器Servlet:976-无法完成 请求org.springframework.dao.InvalidDataAccessApiUsageException:否 交易正在进行中;嵌套异常是 javax.persistence.TransactionRequiredException:中没有事务 进展 这是我的
em.merge()
即可完成,但不会更新数据库,尝试em.flush()
会导致此异常:
2015-12-19 18:01:40调试调度器Servlet:976-无法完成
请求org.springframework.dao.InvalidDataAccessApiUsageException:否
交易正在进行中;嵌套异常是
javax.persistence.TransactionRequiredException:中没有事务
进展
这是我的配置:
@Configuration
@EnableWebMvc
@ComponentScan
@Import({ SecurityConfig.class })
@PropertySource("classpath:application.properties")
@EnableJpaRepositories
@EnableTransactionManagement
public class ApplicationContext extends WebMvcConfigurerAdapter {
@Bean
public DataSource dataSource() {
DriverManagerDataSource datasource = new DriverManagerDataSource();
datasource.setDriverClassName("org.postgresql.Driver");
datasource.setUrl("jdbc:postgresql://localhost/expert");
datasource.setUsername("expert");
datasource.setPassword("expert");
return datasource;
}
@Bean
public JdbcTemplate jdbcTemplate() {
return new JdbcTemplate(dataSource());
}
@Bean
public LocalContainerEntityManagerFactoryBean entityManagerFactory() {
LocalContainerEntityManagerFactoryBean factoryBean
= new LocalContainerEntityManagerFactoryBean();
factoryBean.setDataSource(dataSource());
factoryBean.setPackagesToScan(new String[ ] { "test.model" });
JpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter();
factoryBean.setJpaVendorAdapter(vendorAdapter);
factoryBean.setJpaProperties(this.additionalProperties());
return factoryBean;
}
@Bean
public PlatformTransactionManager transactionManager() {
JpaTransactionManager transactionManager = new JpaTransactionManager();
transactionManager.setEntityManagerFactory(entityManagerFactory().getObject());
return transactionManager;
}
@Bean
public PersistenceExceptionTranslationPostProcessor exceptionTranslation() {
return new PersistenceExceptionTranslationPostProcessor();
}
Properties additionalProperties() {
Properties properties = new Properties();
properties.setProperty("hibernate.show_sql", "true");
properties.setProperty("hibernate.format_sql", "false");
properties.setProperty("hibernate.hbm2ddl.auto", "update");
properties.setProperty("hibernate.dialect", "org.hibernate.dialect.PostgreSQLDialect");
return properties;
}
}
我的服务:
@Service
@Transactional
public class ApiProjectServiceImpl implements ApiProjectService {
@Autowired
private ApiProjectRepository apiProjectRepository;
public Project getProject(Integer id) {
return apiProjectRepository.getProject(id);
}
public Project save(Project project) { return apiProjectRepository.save(project); }
}
以及存储库:
@Repository
public class ApiProjectRepositoryImpl implements ApiProjectRepository {
@PersistenceContext
private EntityManager em;
public Project getProject(Integer id) {
Project project = em.createQuery("select p from Project p where id = " + id, Project.class)
.getSingleResult();
return project;
}
public Project save(Project project) {
project = em.merge(project);
em.flush();
return project;
}
}
尝试保存()时堆栈跟踪:
谢谢
更新1显然,通过从Spring 3.2.8升级到Spring 4.2.0,问题已经解决。我没有对代码做任何更改,我知道需要一个事务,但服务实现用
@Transactional
注释。谢谢大家。就像@Neil Stockton提到的那样,一些实体管理器
函数需要存在事务
以下是doc
关于flush
功能:
void flush()将持久性上下文同步到基础
数据库抛出:TransactionRequiredException-如果没有
事务,或者如果实体管理器尚未加入到
当前事务PersistenceException-如果刷新失败
Merge
函数也是如此:
T合并(T实体)将给定实体的状态合并到
当前持久性上下文。参数:实体-实体实例
返回:状态合并到的托管实例抛出:
IllegalArgumentException-如果实例不是实体或是
已删除实体TransactionRequiredException-如果没有
在容器管理的实体管理器上调用时的事务
类型为PersistenceContextType.TRANSACTION
因此,基本上您想要的是创建新事务
或使用存在的事务。由于您使用的是@EnableTransactionManagement
注释,因此只需对方法进行注释即可
@Transactional(propagation=Propagation.REQUIRED)
public Project save(Project project) {
project = em.merge(project);
em.flush();
return project;
}
有关Spring
事务的更多信息,请访问。更多java中的事务
,强烈推荐。将其添加到数据源文件/配置中
hibernate.allow\u update\u outside\u事务:true
它应该可以工作,但是要确保您的生产环境,正如javadocs for flush()所说的那样。。。仅适用于正在进行的交易。因此,假设您没有启动txn,或者它正在启动JTA,根据文档合并也需要事务处理我没有测试过这一点,但它似乎怀疑您将数据源
和entityManagerFactory
暴露为@Bean
但在这些Bean方法中,您直接调用到其他Bean中定义,而不是将它们放入@Autowire
。我有相同的异常,只是我可以在堆栈跟踪中看到TransactionInterceptor
。我的问题是传递给JpaTransactionManager\setEntityManagerFactory
的EntityManagerFactory
实例。为了产生该异常,我使用了LocalContainerEntityManagerFactoryBean#getNativeEntityManagerFactory
,并将其更正为LocalContainerEntityManagerFactoryBean#getObject()
。幸运的是,我发现了这一点,在完成这项工作后,我发现整个JPA/JTA Hibernate/Spring设置(对于非常特殊的情况)非常令人害怕。我知道需要一个事务,但我已经在服务级别上有了一个@Transactional
注释。我也尝试将注释添加到存储库方法中,但没有任何帮助。通过从Spring3.2.8升级到Spring4.2.0,我显然已经解决了这个问题。我不确定到底是什么问题。
@Transactional(propagation=Propagation.REQUIRED)
public Project save(Project project) {
project = em.merge(project);
em.flush();
return project;
}