2015-03-26 5 views
0

я следующее:Hibernate Spring @Transaction не работает

@Service 
public class AsyncMarketService { 

    @Inject 
    IdentifierManager identifierManager; 

    @Transactional 
    public void getProducts() { 
     identifierManager.getTitleForIdentifier(); 
     } 
} 

Метод службы вызывается из метода @Async.

Я вижу в журнале, что сделка вскрывается:

134331 DEBUG [Company-1] org.springframework.beans.factory.support.DefaultListableBeanFactory - Returning cached instance of singleton bean 'transactionManager' 
134342 DEBUG [Company-1] org.springframework.orm.hibernate4.HibernateTransactionManager - Creating new transaction with name [com.estartup.caller.AsyncMarketService.getProducts]: PROPAGATION_REQUIRED,ISOLATION_DEFAULT; '' 
134343 DEBUG [Company-1] org.springframework.orm.hibernate4.HibernateTransactionManager - Opened new Session [SessionImpl(PersistenceContext[entityKeys=[],collectionKeys=[]];ActionQueue[[email protected] [email protected] [email protected] [email protected] [email protected]c8bd [email protected]46b [email protected]4d [email protected]a6c6 unresolvedInsertDependencies=UnresolvedEntityInsertActions[]])] for Hibernate transaction 
134346 DEBUG [Company-1] org.springframework.orm.hibernate4.HibernateTransactionManager - Preparing JDBC Connection of Hibernate Session [SessionImpl(PersistenceContext[entityKeys=[],collectionKeys=[]];ActionQueue[[email protected] [email protected] [email protected] [email protected] [email protected]c8bd [email protected]46b [email protected]4d c[email protected]6c6 unresolvedInsertDependencies=UnresolvedEntityInsertActions[]])] 
134346 DEBUG [Company-1] org.springframework.jdbc.datasource.DriverManagerDataSource - Creating new JDBC DriverManager Connection to [jdbc:mysql://localhost:3306/Company?zeroDateTimeBehavior=convertToNull] 
134377 DEBUG [Company-1] org.springframework.orm.hibernate4.HibernateTransactionManager - Exposing Hibernate transaction as JDBC transaction [[email protected]] 

Однако, я все еще получаю ошибку:

Caused by: java.util.concurrent.ExecutionException: org.hibernate.HibernateException: get is not valid without active transaction 
at java.util.concurrent.FutureTask.report(FutureTask.java:122) 
at java.util.concurrent.FutureTask.get(FutureTask.java:192) 

, когда я пытаюсь звонить из этого метода (identifierManager.getTitleForIdentifier();) DAO, чтобы получить что-то по id.

Что не так?

EDITED

конфигурации Bean:

@Configuration 
@ComponentScan({ "com.estartup" }) 
@PropertySource("classpath:jdbc.properties") 
@EnableScheduling 
@EnableTransactionManagement 
public class PersistenceConfig { 

    @Autowired 
    Environment env; 

    @Bean 
    public DataSource dataSource() { 
     DriverManagerDataSource driverManagerDataSource = new DriverManagerDataSource(env.getProperty("connection.url"), env.getProperty("connection.username"), 
       env.getProperty("connection.password")); 
     driverManagerDataSource.setDriverClassName("com.mysql.jdbc.Driver"); 
     return driverManagerDataSource; 
    } 

    public PersistenceConfig() { 
     super(); 
    } 

    @Bean 
    public LocalSessionFactoryBean sessionFactory() { 
     LocalSessionFactoryBean factoryBean = null; 
     try { 
      factoryBean = createBaseSessionFactory(); 
      factoryBean.getHibernateProperties().setProperty("hibernate.current_session_context_class", "thread"); 
     } catch (Exception e) { 
      e.printStackTrace(); 
     } 
     return factoryBean; 
    } 

    private LocalSessionFactoryBean createBaseSessionFactory() throws IOException { 
     LocalSessionFactoryBean factoryBean = new LocalSessionFactoryBean(); 
     Properties pp = new Properties(); 
     pp.setProperty("hibernate.dialect", "org.hibernate.dialect.MySQLDialect"); 
     pp.setProperty("hibernate.max_fetch_depth", "3"); 
     pp.setProperty("hibernate.current_session_context_class", "org.springframework.orm.hibernate4.SpringSessionContext"); 
     factoryBean.setDataSource(dataSource()); 
     factoryBean.setPackagesToScan(new String[] { "com.estartup.*" }); 
     factoryBean.setHibernateProperties(pp); 
     return factoryBean; 
    } 

    @Bean 
    @Autowired 
    public HibernateTransactionManager transactionManager(SessionFactory sessionFactory) { 
     HibernateTransactionManager txManager = new HibernateTransactionManager(); 
     txManager.setSessionFactory(sessionFactory); 
     return txManager; 
    } 
} 
+0

Разве сеанс запущен в другом потоке для того, кто выполняет запросы? – BretC

+0

yes - У меня есть сеансовый фильтр, который запускает его при каждом вызове моего REST api – Dejell

+0

Я раньше не использовал аннотацию Async, но нашел эту страницу https://spring.io/guides/gs/async- method /, и он говорит: «Метод findPage помечен аннотацией Spring Async, указывающий, что он будет работать в отдельном потоке», поэтому я подозреваю, что отдельный поток не имеет того же сеанса - просто гадание – BretC

ответ

1

Одна вещь, которую вы могли бы попробовать это отбросить @Transactional аннотацию и вручную открыть сеанс самостоятельно (не уверен, что есть лучший способ .. .)

@Service 
public class AsyncMarketService { 

    @Inject 
    IdentifierManager identifierManager; 

    @Inject 
    SessionFactory sessionFactory; 

    public void getProducts() { 
     Session session = sessionFactory.openSession(); 
     Transaction tx = null; 

     try { 
      identifierManager.getTitleForIdentifier(); 
     } catch(Exception e) { 
      if(tx != null) tx.rollback(); 
     } finally { 
      session.close(); 
     } 
    } 
} 

Если вы обнаружите, что делаете это более одного раза, возможно, напишите еще один компонент, который имеет способ tha t берет замыкание или что-то в этом роде.

Если я найду более элегантный способ в ближайшие несколько минут, я буду держать вас в курсе.

+0

Я попробую это спасибо – Dejell

+0

Что делать, если есть уже открытая транзакция? – Dejell

+0

@Dejel - см. Http://stackoverflow.com/questions/8046662/hibernate-opensession-vs-getcurrentsession – BretC

0

Попробуйте перевести @Transactional на вызывающий асинхронный метод. Транзакция не распространяется по иерархии вызовов от одного компонента Spring к другому, поскольку асинхронный метод планируется и выполняется позже исполнителем задачи.

+0

nope не помогает – Dejell

Смежные вопросы