title: Spring hibernate transactions - catch 22
body: <p>I'm using Spring and Hibernate with annotation-driven transactions.
  When running my application I've received an exception "createCriteria is not valid without active transaction". According to this <a href="https://stackoverflow.com/questions/7500030/spring-hibernate-exception-createcriteria-is-not-valid-without-active-transacti">Spring/Hibernate Exception: createCriteria is not valid without active transaction</a> the solution is to remove the line <code>&lt;property name="current_session_context_class"&gt;thread&lt;/property&gt;</code> from sessionFactory configuration.</p>
  
  <p>However, I also need to do some transactional work in my @PostConstruct method (initialization from DB). @PostConstruct methods can't be transactional, so I open a manual transaction - but this does not work when I remove the the above line (getting an exception <code>org.hibernate.HibernateException: No Hibernate Session bound to thread, and configuration does not allow creation of non-transactional one here</code>). According to several sources the solution to this is to add <code>&lt;property name="current_session_context_class"&gt;thread&lt;/property&gt;</code> to configuration...</p>
  
  <p>This is my code (I'm aware it's not too nice and clean - I've been fiddling with it to understand what the problems were):</p>
  
  <p>`@Transactional
  public class TaskControllerImpl implements TaskController {</p>
  
  <pre><code>@Autowired
  TaskDAO taskDAO;
  
  @Autowired
  MethodDAO methodDAO;
  
  @Autowired
  SessionFactory sessionFactory;
  
  ExecutorService threadPool = Executors.newCachedThreadPool();
  
  
  /**
   * Map of method name to TaskExecutor for all defined methods
   */
  private Map&lt;String, TaskExecutor&gt; executorsByMethod;
  
  final Logger logger = LoggerFactory.getLogger(TaskControllerImpl.class);
  
  /**
   * Initializes the mapping of method name to TaskExecutor
   */
  @PostConstruct
  public void init() {
      // @Transactional has no effect in @Postconstruct methods so must do this manually
      Transaction t = sessionFactory.getCurrentSession().beginTransaction();
      executorsByMethod = new HashMap&lt;String, TaskExecutor&gt;();
      List&lt;Method&gt; methods = methodDAO.findAll();
      for (Method method : methods) {         
          if (method.getExecutorClassName() != null) {
              try {
                  TaskExecutor executor = createTaskExecutor(method);
                  executorsByMethod.put(method.getName(), executor);
              } catch (Throwable e) {
                  logger.error("Coud not create/instantiate executor " + method.getExecutorClassName());
                  e.printStackTrace();
              }
          }       
      }
  
      t.commit();
  }
  
  @Override
  public void run() {
      Collection&lt;Task&gt; tasksToExecute = fetchTasksToExecute();
      for (Task task : tasksToExecute) {
          String method = task.getMethod().getName();
          executorsByMethod.get(method).addTask(task);
      }
  }
  
  /**
   * Fetches all tasks which need to be executed at the current time
   * 
   * @return
   */
  private Collection&lt;Task&gt; fetchTasksToExecute() {
      try {
          Search search = new Search();
          search.addFilterLessThan("actionDate", DateUtil.now());
          search.addFilterEqual("status", TaskStatus.PENDING.getCode());
          search.addSort("actionDate", false);
          return taskDAO.search(search);
      } catch (Throwable e) {
          // TODO Auto-generated catch block
          e.printStackTrace();
          return null;
      }
  }
  </code></pre>
  
  <p>`</p>
  
  <p>Configuration:</p>
  
  <p>`   </p>
  
  <pre><code>&lt;!-- Configure a JDBC datasource for Hibernate to connect with --&gt;
  &lt;bean id="dataSource"
      class="org.springframework.jdbc.datasource.DriverManagerDataSource"&gt;
      &lt;property name="driverClassName" value="com.mysql.jdbc.Driver" /&gt;
      &lt;property name="url" value="${connection.url}" /&gt;
      &lt;property name="username" value="${connection.username}" /&gt;
      &lt;property name="password" value="${connection.password}" /&gt;
  &lt;/bean&gt;
  
  &lt;!-- Configure a Hibernate SessionFactory --&gt;
  &lt;bean id="sessionFactory"
      class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean"&gt;
      &lt;property name="dataSource" ref="dataSource" /&gt;
      &lt;property name="packagesToScan" value="com.grroo.model" /&gt;
      &lt;property name="hibernateProperties"&gt;
          &lt;props&gt;
              &lt;prop key="hibernate.dialect"&gt;org.hibernate.dialect.MySQLDialect&lt;/prop&gt;
              &lt;prop key="hibernate.show_sql"&gt;false&lt;/prop&gt;
              &lt;!-- prop key="hibernate.current_session_context_class"&gt;thread&lt;/prop--&gt;
              &lt;prop key="hibernate.connection.zeroDateTimeBehavior"&gt;convertToNull&lt;/prop&gt;
          &lt;/props&gt;
      &lt;/property&gt;
  &lt;/bean&gt;
  
  &lt;bean id="transactionManager"
      class="org.springframework.orm.hibernate3.HibernateTransactionManager"&gt;
      &lt;property name="sessionFactory" ref="sessionFactory" /&gt;
  &lt;/bean&gt;
  </code></pre>
  
  <p></p>
  
  <pre><code>&lt;tx:annotation-driven/&gt; 
  </code></pre>
  
  <p> `</p>
  
  <p>So I'm in a bit of a catch-22 here on how to make both init() and run() work. Any ideas?</p>