Replicating Component/s standard field from a subtask to its parent issue to a newly created subtask does not work

Rusi Popov
Rising Star
Rising Star
Rising Stars are recognized for providing high-quality answers to other users. Rising Stars receive a certificate of achievement and are on the path to becoming Community Leaders.
April 10, 2016

Dear colleagues,

I am fighting with a problem caused by some specifics of the Component/s standard field:

  • in a listener I capture the transition to Done state of each subtask
  • the listener transfers specific standard and custom fields to the parent issue
  • the listener transitions the parent to to a new state
  • in the new parent issue state the listener creates a new subtask and copies some parent issue fields to it.

The problem is that all standard and custom fields are copied to the parent and to the newly created subtask, except the Component/s standard field. The newly created subtask inherits the original value of the Component/s field before the change. Note that no other standard or custom fields experience this problem - the copied values from the parent to the newly created subtask are exactly those provided by the initial subtask.

The code uses the public API IssueService and IssueInputParameters for updating, transitioning and creating the issues.

Here is a demonstration log of the events and changes happening:

Enter event 13 on issue MAD-458(h=759368613) 
 Replicate from MAD-458(h=759368613) to MAD-415(h=421154895)
     set issue input parameter Components -> [10300, 10301]
     set issue input parameter Affected Versions -> [10301]
     set issue input parameter Environment -> null
     set issue input parameter Description -> push 443
     
     Enter event 2 on issue MAD-415(h=1679514000) 
     Exit event 2 on issue MAD-415(h=1679514000)
     
     Issue MAD-415(433405394) Components [ProjectComponentImpl { name='MAD.C1',... id='10300' }, ProjectComponentImpl { name='MAD.C2',... id='10301' }]
     
     transition issue MAD-415(h=433405394)  action: Proceed
     
     Enter event 13 on issue MAD-415(h=473479075) 
     When constructing sub-task the parent Components are [ProjectComponentImpl { name='MAD.C1',... id='10300' }]
         set issue input parameter Summary -> Components are not transferred from subtask through parent to subtask
         set issue input parameter Description -> push 443
         set issue input parameter Reporter -> rico
         set issue input parameter Components -> [10300]
         set issue input parameter Affected Versions -> [10301]
         set issue input parameter Environment -> null
         
         Enter event 1 on issue MAD-459(h=1067168956)
         Exit event 1 on issue MAD-459(h=1067168956)
         
         Constructed Issue MAD-415(473479075) Components [ProjectComponentImpl { name='MAD.C1', description='', lead='', assigneeType='0', projectId='11000', id='10300' }]
    Exit event 13 on issue MAD-415(h=473479075)
    
    transition issue MAD-415  action: Proceed succeeded.
Exit event 13 on issue MAD-458(h=759368613)

The log indicates the System.identityHashCode of the issue objects referred.

In this case:

  • MAD-458 is the subtask whose generic issue event (13) is captured by the listener and sets the IssueInputParameters to update the parent issue (MAD-415)
  • MAD-415 is the parent issue
  • line 3 demonstrates that 2 components are set to the parent issue
  • lines 8,9 demonstrate the nested event of updating the parent issue (MAD-415)
  • line 11 demonstrates the result of the update (in the outer event) by getting the value of Component/s field of the updated parent issue (MAD-415) - 2 components are returned
  • line 13 indicates that the listener transitions MAD-415
  • line 15 presents the general issue event (13) on MAD-415 as a result of the transition
  • line 16 shows that in during that event the Component/s field of MAD-415 contains 1 component (wrong)
  • the next stubtask is created with the Component/s list of 1 component
  • the GUI shows that
    • the Component/s field MAD-415 contains the correct 2 components
    • the newly constructed subtask MAD-458 contains wrong 1 component, copied from MAD-415 before the update
    • any other fields of the new newly created task have the correct values, as of the original subtask and copied to the parent

I assume the problem is caused by some caching and the nested transactions, but the nested transactions are logical and only the outer-most transaction (for event 13 on MAD-458) is physical/database one and it is committed at the exit of the event handling.

How could problems be solved? How could the nested event (13) access the updated parent issue?

Thank you in advance for your help

Rusi Popov

1 answer

0 votes
Rusi Popov
Rising Star
Rising Star
Rising Stars are recognized for providing high-quality answers to other users. Rising Stars receive a certificate of achievement and are on the path to becoming Community Leaders.
June 9, 2016

During the implementation of this design, the following important specifics (even bugs) of JIRA were revealed:

  • Revealed that the mechanism the workflow uses to transfer parameters to the Conditions, Validators and Post-functions works/is used as a container of the issue objects for most of the standard functions, conditions, validators:

    • Most of the standard Conditions, Validators and Post-functions use to store the whole issue (from that cache) in the database.

    • JIRA persistence does not provide optimistic locking, thus collision of the issue versions happen uncontrolled, when custom post functions update the issue in DB and then the standard functions take over. 

    • For example:
      • a post function updates the issue in the DB
      • the standard function to create a history record or store the comment
        • takes the issue from the parameters map (the mechanism OsWorkflow uses to send the issue to the functions, conditions, etc.), which is already obsolete
        • stores it as a whole in the database
      • this way the second function (partially) overwrites the changes in DB the first one did

    In order to resolve this conflict, I set up our custom functions to update the "cached" issue in the parameters map.

  • When changes happen in a single transaction, some of the issue's fields cannot "see" them, because:
    • there are standard fields with multiple values, which are configured separately. They are loaded in the issue lazily on need. This happens through "managers" like ProjectComponentManager, that uses the OfBizDelegator to access the database. The latter is documented to use a new database connection, out of the current transaction.
    • as a result, when a change is made in the current transaction (local TX 1 on JDBC connection 1), the access to changes in the same issue through another issue copy would use another JDBC connection with its own local transaction 2
    • as TX 1 and TX 2 are both not completed and they are isolated, the retrieved value is one BEFORE THE CHANGE in the current transaction.

Revealed that:

FunctionIssue Instance Used
com.atlassian.jira.workflow.function.event.FireIssueEventFunctionFires the event on the IN MEMORY issue parameter
com.atlassian.jira.workflow.function.issue.GenerateChangeHistoryFunctionStores the IN MEMORY parameter issue
com.atlassian.jira.workflow.function.issue.IssueReindexFunctionReindexes the IN-MEMORY issue
com.atlassian.jira.workflow.function.issue.UpdateIssueFieldFunctionUpdates the issue IN MEMORY, stores fields other than STATUS, ESTIMATE (like RESOLUTION, ASSIGNEE) directly in DB
com.atlassian.jira.workflow.function.issue.UpdateIssueStatusFunctionUpdates the parameter issue's state IN MEMORY
com.atlassian.jira.workflow.function.misc.CreateCommentFunctionConstructs a comment parameter, adds it to the parameter issue, loads the issue from DB, add the comment and stores it as a whole

Both these issues cause the reported misbehavior.

Suggest an answer

Log in or Sign up to answer