2012-01-17 5 views
2

У меня есть Spring/JPA/Groovy/гибернации стек, (примечание: не Grails), и я нахожу, что я получаю No session found for current thread когда пытаясь выполнить некоторую работу @Transactional.Groovy/Hibernate/@Transaction не возвращает сеанса найденный для текущего потока

У меня есть класс контроллера, который после @PostConstruct вызывает метод @Transactional другого класса, который пытается заполнить базу данных некоторыми образцами данных, которые будут использоваться в симуляции.

Вот controller класс:

@Component 
public class SimulationController { 

    private TransactionTemplate transactionTemplate; 
    @Autowired 
    private PlatformTransactionManager transactionManager; 
    @Autowired 
    private IPublisher publisher; 

    @PostConstruct 
    public void intialize() 
    { 
     this.transactionTemplate = new TransactionTemplate(transactionManager); 
     transactionTemplate.execute(new TransactionCallbackWithoutResult() { 
      @Override 
      protected void doInTransactionWithoutResult(TransactionStatus arg0) { 
       racePublisher.populateData(); 
      } 
     }); 
    } 
    // Also tried, with no success:  
    // @PostConstruct 
    // public void initialize() 
    // { 
    //  publisher.populateData(); 
    // } 
} 

Как вы можете видеть, я отошел от чистого @Transactional подхода в @PostConstruct по причинам, рассмотренным here.

Моего IPublisher является заводным классом следующим образом:

@Component 
class Publisher implements IPublisher { 

@Autowired 
IStockDAO stockDAO 

void populateData() 
{ 
    createStock() 
} 
@Transactional 
void createStock() 
{ 
    def list = [new Stock(ticker: "ADBE", name: "Adobe"), 
       new Stock(ticker: "MSFT", venueCode: "Microsoft")] 
    list.each { stockDAO.create it } 
} 

который является реализацией:

public interface IPublisher { 

    public void populateData(); 
    public void createStock(); 
} 

Примечания, я также пытался маркировки populateData() как @Transactional, без эффекта.

В моем классе контекста Spring я определяю <tx:annotation-driven/>.

Насколько я могу судить, я все сделал правильно. Однако я не могу заставить это работать.

Что еще требуется?

Обновлено: Вот бобы настройки мои связанные DATAACCESS бобы:

<beans> 
<bean id="transactionManager" 
     class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> 
     <property name="dataSource" ref="dataSource" /> 
    </bean> 

    <tx:annotation-driven/> 

    <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource"> 
     <property name="driverClassName" value="com.mysql.jdbc.Driver" /> 
     <property name="url" value="jdbc:mysql://${database.host}:${database.port}/${database.name}" /> 
     <property name="username" value="${database.username}" /> 
     <property name="password" value="${database.password}" /> 
     <property name="initialSize" value="5" /> 
     <property name="maxActive" value="50" /> 
    </bean> 
    <bean id="sessionFactory" 
     class="org.springframework.orm.hibernate4.LocalSessionFactoryBean"> 
     <property name="dataSource" ref="dataSource" /> 
     <property name="packagesToScan"> 
      <list> 
       <value>com.mangofactory.concorde</value> 
      </list> 
     </property> 
     <property name="hibernateProperties"> 
      <props> 
       <prop key="hibernate.dialect">${hibernate.dialect}</prop> 
       <prop key="hibernate.cache.provider_class">org.hibernate.cache.HashtableCacheProvider 
       </prop> 
       <prop key="hibernate.show_sql">true</prop> 
       <prop key="hibernate.format_sql">true</prop> 
       <prop key="hibernate.hbm2ddl.auto">update</prop><!-- use create for full drop/create --> 
       <prop key="hibernate.connection.autocommit">true</prop> 
       <prop key="hibernate.statement_cache.size">0</prop> 
       <prop key="hibernate.jdbc.batch_size">20</prop> 
      </props> 
     </property> 
    </bean> 
    <beans> 
+0

Как определяется ваш transactionManager? – mrembisz

+0

@mrembisz Я добавил объявления на вопрос –

ответ

3

Вы должны использовать HibernateTransactionManager вместо DataSourceTransactionManager.

+0

Спасибо! Вот и все! Спасибо! –

+0

@mrembisz +1 за то, что заметил простую вещь :) –

0

Есть основные проблемы, связанные с кодом. Транзакционная граница начинается с метода createStock класса Publisher и заканчивается там. Он не распространяется на ваш контроллер. Используйте вызовы запросов БД внутри транзакции. то есть внутри метода, который имеет аннотацию Transactional. Иначе это никогда не сработает.

+0

Не уверен, что понимаю, что вы здесь говорите. Я использую вызовы запросов БД внутри транзакции - вызов 'create' завершается внутри блока' @ Transactional' –

+0

@MartyPitt Коды шаблонов транзакций находятся за пределами границы транзакции. Он не будет работать в методе intialize(). Он будет работать в методе с транзакционной аннотацией. –

+0

@AravindA 'transactionTemplate.execute()' является api эквивалентом '@ Transactional'. Этот код должен работать с ИМО. – mrembisz

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