2016-09-08 19 views
1

У меня есть приложение Spring, которое использует JTA (попробовал и atomikos и bitronix с той же проблемой) + JPA (Hibernate), и я запускаю в следующей задачеЗакрытие транзакционного синхронизатора Spring JPA перед завершением транзакции, когда присутствует внешний ключ

Все работает с тех пор, пока я не попытаюсь использовать внешние ключи (например, отношения OneToOne, каскад не имеет значения).

Когда я делаю, то синхронизатор весной сделка принудительно закрыть менеджер лица, прежде чем сделка будет завершена, и когда менеджер транзакций пытается совершить то я просто получаю:

ERROR: HHH000346: Error during managed flush [Session/EntityManager is closed] 

Там нет других журналов, которые укажите, почему весна рано закрывает менеджера объекта.

Я узнал, что если я делаю entitymenager.flush(), это решает проблему в наиболее случаях, но не для всех.

У меня есть проект с юнит-тестов, которые копируют проблему: https://github.com/Kloudtek/ktspring (модульные тесты являются для автономного/atomikos-Артемида-зимуют

Вот выдержка из того, что я использую

@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; 
    }); 
} 

ответ

1

у нас была аналогичная проблема с пружиной 4.3.2 и Hibernate 5.2.2 понижение зимуют 5.1.1 решена наша проблема

+0

есть еще вопросы весной 4.3.2 вместе с Hibernate 5.2.2 ех: https: //jira.spring.io/browse/SPR-14676 – Joram

+0

Фантастично, что действительно решило проблему. Вы случайно не знаете, является ли эта конкретная проблема ошибкой в ​​спящем режиме или ошибка весной? –

+0

Не совсем решение, я думаю, просто обходное решение. Я не заглядывал в детали, но hibernate 5.2 содержит довольно значительные изменения в подготовке к 6.0 – Joram