title: No existing transaction found for transaction marked with propagation 'mandatory' Exception in DAO classes
body: <p>I have an activity class that is annotated as a component that calls an action class: </p>
  
  <pre><code> @Transactional(propagation = Propagation.REQUIRED, readOnly = false, rollbackFor = NonRetryableException.class)
   public ExecuteTemplateResponse executeTemplate(ExecuteTemplateRequest request)
   {
        actionExecutionContext = action.execute(actionExecutionContext);
   }
  </code></pre>
  
  <p>My action class is also annotated with @Component and has the following execute method:</p>
  
  <pre><code>@Transactional(propagation = Propagation.MANDATORY)
  @Override
  public ActionExecutionContext execute(ActionExecutionContext actionExecutionContext)
  {
      iogl = ioglDao.create(iogl);
      return actionExecutionContext;
  }
  </code></pre>
  
  <p>The ioglDao class is annotated as @Repository and has the following create method:</p>
  
  <pre><code>@Transactional(propagation = Propagation.MANDATORY)
  @Override
  public InventoryOwnerGroupLocation create(InventoryOwnerGroupLocation iogl)
  {
      // injected
      Session session = sessionFactory.getCurrentSession();
  
      session.save(iogl);
  
      return iogl;
  }
  </code></pre>
  
  <p>I believe that the Transaction should propagate from the Service Layer to the dao class, but it seems it's not. I get the No existing transaction found for transaction marked with propagation 'mandatory' Exception.</p>
  
  <p>Why isn't the transaction propagating to my DAO classes?</p>
  
  <p>EDIT: added all of the activity class</p>
  
  <pre><code>@Service("FASelfServiceMappingService")
  @Component
  public class ExecuteTemplateActivity extends Activity
  {
      private final static Logger logger = Logger.getLogger(ExecuteTemplateActivity.class);
  
  
  // mapper framework to interact with DynamoDB database
  private final DynamoDBMapper dynamoDBMapper;
  
  // class to convert external models to internal models
  private final InternalModelToDynamoDBModelConverter internalToDynamoDBConverter;
  private final InternalModelToOracleModelConverter internalToOracleConverter;
  private final CoralModelToInternalModelConverter coralToInternalConverter;
  
  // class to generate list of actions
  private final ActionGenerator actionGenerator;
  
  // status constants
  private static final String STATUS_COMPLETED = "COMPLETED";
  private static final String STATUS_FAILED = "FAILED";
  
  @Inject
  public ExecuteTemplateActivity(InternalModelToDynamoDBModelConverter internalToDynamoDBConverter,
                                 InternalModelToOracleModelConverter internalToOracleConverter,
                                 CoralModelToInternalModelConverter coralToInternalConverter,
                                 ActionGenerator actionGenerator,
                                 DynamoDBMapper dynamoDBMapper)
  {
      this.internalToDynamoDBConverter = internalToDynamoDBConverter;
      this.internalToOracleConverter = internalToOracleConverter;
      this.coralToInternalConverter = coralToInternalConverter;
      this.actionGenerator = actionGenerator;
      this.dynamoDBMapper = dynamoDBMapper;
  }
  
  
  @Transactional(propagation = Propagation.REQUIRED, readOnly = false, rollbackFor = NonRetryableException.class)
   @Operation("ExecuteTemplate")
   public ExecuteTemplateResponse executeTemplate(ExecuteTemplateRequest request) throws RetryableException, NonRetryableException
   {
       try
       {
           logger.info("Input given: " + request);
  
           // convert request input to an internal request
           Request internalRequest = coralToInternalConverter.coralRequestToInternal(request);
           logger.info("Successfully converted External Request to internal Request.");
  
           String templateName = getTemplateName(internalRequest);
           logger.info("Template Name extracted from the request: " + templateName);
  
           Template template = getTemplateFromDynamo(internalRequest, templateName);
           logger.info("Template read from dynamoDB table: " + template);
  
           // Generate a map from string to Action objects associated with the retrieved template
           List&lt;Action&gt; listOfActions = actionGenerator.generateActions(template.getActions());
           logger.info("Actions generated for template " + templateName + ": " + listOfActions);
  
           // Generate the action context for actions to pass to each other to keep track of state
           ActionExecutionContext actionExecutionContext = internalToOracleConverter.inputsToActionExecutionContext(internalRequest.getInputs());
          logger.info("Built ActionExecutionContext:" + actionExecutionContext);
  
           // execute the actions
           for (Action action : listOfActions)
           {
               actionExecutionContext = action.execute(actionExecutionContext);
           }
           logger.info("All actions executed successfully.");
           // request was completed successfully, create request in Request table
           String requestId = createRequestInDynamo(internalRequest, STATUS_COMPLETED);
  
           ExecuteTemplateResponse executeTemplateResponse = new ExecuteTemplateResponse();
           executeTemplateResponse.setRequestId(requestId);
  
           logger.info("Service call "+ this.getClass() +" succeeded.");
           return executeTemplateResponse;
           }
       catch (RetryableException re)
       {
           logger.error("Retryable Exception occurred in activity.", re);
           throw re;
       }
       catch (NonRetryableException nre)
       {
           logger.error("NonRetryable Exception occurred in activity.", nre);
           throw nre;
       }
       catch (Exception e)
       {
           logger.error("Unknown Exception occurred in activity.", e);
           throw new NonRetryableException("Unexpected error", e);
       }
   }
  
  /**
   * extracts the templateName from the internalRequest
   * @param internalRequest internal model of the request
   * @return templateName
   */
  private String getTemplateName(Request internalRequest)
  {
      Validate.notNull(internalRequest, "internalRequest must not be null.");
  
      String templateName;
      try
      {
          // extract template name from request
          templateName = internalRequest.getTemplateName();
          Validate.notNull(templateName, "templateName must not be null.");
      }
      catch (IllegalArgumentException iae)
      {
          createRequestInDynamo(internalRequest, STATUS_FAILED);
          logger.error("Invalid input: templateName is null.");
          throw new NonRetryableException("Invalid input: templateName is null.", iae);
      }
  
      return templateName;
  }
  
  /**
   * Retrieves the template object associated with given templateName
   * @param internalRequest internal model of request
   * @param templateName name of template to retrieve
   * @return Template object
   */
  private Template getTemplateFromDynamo(Request internalRequest, String templateName)
  {
      Validate.notNull(internalRequest, "internalRequest must not be null.");
      Validate.notNull(templateName, "templateName must not be null.");
  
      Template template;
      try
      {
          // read the template with given template name from Templates table
          template = dynamoDBMapper.load(Template.class, templateName);
      }
      catch (DynamoDBMappingException ddbme)
      {
          createRequestInDynamo(internalRequest, STATUS_FAILED);
          logger.error("Reading template from dynamoDB table failed.", ddbme);
          throw new NonRetryableException("Incorrect class annotation or incompatible with class", ddbme);
      }
      catch (AmazonClientException ace)
      {
          createRequestInDynamo(internalRequest, STATUS_FAILED);
          logger.error("Reading template from dynamoDB table failed.", ace);
          throw new RetryableException("Error when loading template from dynamoDB", ace);
      }
  
      return template;
  }
  </code></pre>
  
  <p>EDIT:</p>
  
  <p>Transaction Manager configuration:</p>
  
  <pre><code>   &lt;tx:annotation-driven transaction-manager="txManager"
                            mode="proxy" proxy-target-class='true' /&gt;
  
      &lt;bean id="txManager"
            class="org.springframework.orm.hibernate4.HibernateTransactionManager"&gt;
          &lt;property name="sessionFactory" ref="sessionFactory" /&gt;
          &lt;property name="dataSource" ref="dataSource" /&gt;
      &lt;/bean&gt;
  </code></pre>