Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/hibernate/5.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
存在外键时,Spring事务同步器在事务结束前关闭JPA实体管理器_Spring_Hibernate_Jta_Spring Transactions_Spring Orm - Fatal编程技术网

存在外键时,Spring事务同步器在事务结束前关闭JPA实体管理器

存在外键时,Spring事务同步器在事务结束前关闭JPA实体管理器,spring,hibernate,jta,spring-transactions,spring-orm,Spring,Hibernate,Jta,Spring Transactions,Spring Orm,我有一个spring应用程序,它使用JTA(用同样的问题尝试了atomikos和bitronix)+JPA(Hibernate),我遇到了以下问题 在我尝试使用外键之前,一切都会正常工作(例如,一对一的关系,cascade不会产生任何影响) 当我这样做时,spring事务同步器会在事务完成之前强制关闭实体管理器,当事务管理器尝试提交时,我只会得到: ERROR: HHH000346: Error during managed flush [Session/EntityManager is clo

我有一个spring应用程序,它使用JTA(用同样的问题尝试了atomikos和bitronix)+JPA(Hibernate),我遇到了以下问题

在我尝试使用外键之前,一切都会正常工作(例如,一对一的关系,cascade不会产生任何影响)

当我这样做时,spring事务同步器会在事务完成之前强制关闭实体管理器,当事务管理器尝试提交时,我只会得到:

ERROR: HHH000346: Error during managed flush [Session/EntityManager is closed]
没有其他日志表明spring提前关闭实体管理器的原因

我发现,如果我使用EntityEnabler.flush(),大多数情况下都能解决问题,但不是所有情况

我有一个项目,其中的单元测试复制了这个问题:(单元测试是针对单机版/atomikos artemis hibernate的测试

这里是我使用的一个摘录

@Bean(initMethod = "init", destroyMethod = "shutdownForce")
public UserTransactionServiceImp userTransactionService() {
    Properties p = new Properties();
    p.setProperty("com.atomikos.icatch.service", "com.atomikos.icatch.standalone.UserTransactionServiceFactory");
    p.setProperty("com.atomikos.icatch.default_jta_timeout","30000");
    return new UserTransactionServiceImp(p);
}

@Bean(initMethod = "init", destroyMethod = "close")
@DependsOn("userTransactionService")
public UserTransactionManager UserTransactionManager() {
    UserTransactionManager userTransactionManager = new UserTransactionManager();
    userTransactionManager.setForceShutdown(false);
    userTransactionManager.setStartupTransactionService(false);
    return userTransactionManager;
}

@Bean
@DependsOn("userTransactionService")
public UserTransactionImp userTransactionImp() throws SystemException {
    UserTransactionImp userTransactionImp = new UserTransactionImp();
    return userTransactionImp;
}

@Bean
@DependsOn("userTransactionService")
public JtaTransactionManager jtaTransactionManager() {
    return new JtaTransactionManager(UserTransactionManager(), UserTransactionManager());
}

@Bean
public JPAParams jpaParams() {
    Properties p = new Properties();
    p.setProperty("hibernate.connection.handling_mode", "DELAYED_ACQUISITION_AND_RELEASE_AFTER_TRANSACTION");
    p.setProperty("hibernate.current_session_context_class", "jta");
    p.setProperty("hibernate.transaction.jta.platform", AtomikosPlatform.class.getName());
    return new JPAParams(p);
}

@Bean
public LocalContainerEntityManagerFactoryBean entityManager() {
    LocalContainerEntityManagerFactoryBean entityManager = new LocalContainerEntityManagerFactoryBean();
    if (config.isJtaDatasource()) {
        entityManager.setJtaDataSource(config.getDataSource());
    } else {
        entityManager.setDataSource(config.getDataSource());
    }
    Properties p = new Properties();
    p.putAll(config.getJpaProperties());
    if (jpaParamsList != null) {
        for (JPAParams jpaParams : jpaParamsList) {
            p.putAll(jpaParams.getProperties());
        }
    }
    entityManager.setJpaProperties(p);
    entityManager.setPackagesToScan(config.getPackageToScan());
    entityManager.setPersistenceProvider(new HibernatePersistenceProvider());
    return entityManager;
}

@Entity
public class TestObj {
    @Id
    private int id;
    @OneToOne
    private TestObj2 testObj2;

    public TestObj() {
    }

    public TestObj(int id) {
        this.id = id;
    }

    public TestObj(int id, TestObj2 testObj2) {
        this.id = id;
        this.testObj2 = testObj2;
    }

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }
}

@Entity
public class TestObj2 {
    @Id
    private int id;

    public TestObj2() {
    }

    public TestObj2(int id) {
        this.id = id;
    }

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }
}

public void testDb() {
    tx.execute(status -> {
        entityManager.persist(new TestObj3(0));
        TestObj2 o2 = new TestObj2(0);
        entityManager.persist(o2);
        TestObj o1 = new TestObj(0, o2);
        entityManager.persist(o1);
        // If i flush the problem disapears
        // entityManager.flush();
        return null;
    });
}

Spring4.3.2和Hibernate5.2.2也有类似的问题
将hibernate降级到5.1.1解决了我们的问题

在spring 4.3.2和hibernate 5.2.2中仍然存在一些问题。ex:这确实解决了问题。你会知道这个特定的问题是hibernate中的错误还是spring中的错误吗?我认为这并不是一个真正的解决方案,只是一个变通方法。我没有研究细节,但是Hibernate5.2在为6.0做准备时包含了一些突破性的变化