Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/396.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java Spring JPA:没有正在进行的事务_Java_Spring_Spring Mvc_Jpa - Fatal编程技术网

Java Spring JPA:没有正在进行的事务

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:中没有事务 进展 这是我的

我在Spring应用程序中持久化实体时遇到问题。只需执行
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;
    }