It's not the same without you

Join the community to find out what other Atlassian users are discussing, debating and creating.

Atlassian Community Hero Image Collage

Update an issue field in a listener - changes are not made

Hello,

I have written a Jira listener where I need to update some fields. The strange thing is that I manage to update any custom field value but none of the issue (native) fields. This is my code in the listener:

Issue issue = issueEvent.getIssue();
MutableIssue mutableIssue = issueManager.getIssueObject(issue.getKey());

mutableIssue.setSummary("this is a setSummary test!");		 
mutableIssue.setCustomFieldValue(myCustomField(), "custom field test");
issueManager.updateIssue(user, mutableIssue, com.atlassian.jira.event.type.EventDispatchOption.DO_NOT_DISPATCH, false);

In this example, the custom field is updated successfully. But nothing happens to the summary field.

I've also tried with

OrderableField field = fieldManager.getOrderableField(fieldId);
        
Map fieldValuesHolder = new HashMap();
field.populateFromParams(fieldValuesHolder,MapBuilder.build(fieldId, toArr(fieldValue))); // toArr just puts the value in an array
        
FieldLayoutItem fieldLayoutItem = fieldLayoutManager.getFieldLayout(issue).getFieldLayoutItem(field);  
        
field.updateIssue(fieldLayoutItem, issue, fieldValuesHolder);
        
if (issue.getModifiedFields().containsKey(field.getId()))
{
field.updateValue(fieldLayoutItem, issue, issue.getModifiedFields().get(field.getId()), new DefaultIssueChangeHolder());
        issue.getModifiedFields().remove(field.getId());
}

The same thing happens. Using this code I can modify custom fields but i cannot modify issue fields like summary, description, etc.

On the other hand, if i call this from a post function it works fine for any field. But in listeners it works only for custom fields.

Does anyone have any idea why this is happening? What am i doing wrong? Is is possible to modify an issue field from a listener? How could this be done?

Thank you very much for your help,

Dan

UPDATE: After further research I have noticed that this problem exists only if the listener is triggered by an workflow transition. It works fine for events that are not fired by workflow transitions (like UPDATE for instance). Also, I have noticed that this problem exists for system fields like Summary and Description. There is no problem with Fix Version or any Custom Field. My Jira version is 5.1.

11 answers

1 accepted

10 votes
Answer accepted

The problem you are facing it's very simple:

These lines provoke all the trouble:

Issue issue = issueEvent.getIssue(); //here is the issue
MutableIssue mutableIssue = issueManager.getIssueObject(issue.getKey()); //here is a copy of the issue !!!
In fact, it should be like that:
MutableIssue issue = (MutableIssue)issueEvent.getIssue();
What you are doing is to create a copy of the issue, you modify the copy, but you cannot control the order the objects are saved ...

HTH

Hey hey ! Not so fast ! Paranoia pays over time. Please code it like this:

Issue issue = issueEvent.getIssue();

if(issue instanceof MutableIssue) {

//cast it

} else {

//cross your fingers and load it as before !.

}

Yes, you are right!

Now it works no matter if Autowatch is enabled or not. I've only tested for Summary but I suppose it works for anything. The code in my listener is:

Issue issue = issueEvent.getIssue(); 
		MutableIssue mutableIssue = (MutableIssue)issue;
	    	mutableIssue.setSummary("this is a setSummary test!");    
	    	issueManager.updateIssue(eventUser, mutableIssue, com.atlassian.jira.event.type.EventDispatchOption.DO_NOT_DISPATCH, false);

I didn't know the issueEvent.getIssue() was getting in fact an editable version of the issue. I thought it was "read-only", this is why I was making a copy.

Thank you Radu,

Dan

Correct again! Thanks,

Dan

Thank you folks for the advice.

Hope my experience will be useful for subsequent readers.

I was using IssueService.update() to update system fields from a Listener. The strange thing also happened to me when the fields are not updated in according to the issue history. And this only happens for Issue Created event.

My solution is to modify the in-memory mutableIssue (as Radu's answer) together with the IssueService.update(). Thus if there is any other listeners that is handling the issue event, it will get also get a copy of the updated MutableIssue.

Try mutableIssue.store() before the updateIssue() call. This is to store values which are a direct part of the issue object.

Henning

Hi Henning,

Thank you for your answer.

I have tried already with store too and I have exactly the same problem.

The javadoc says that mutableIssue.store() is deprecated since Jira 5.0 and that the issueManager.updateIssue() should be used instead. This is how i've got to use the updateIssue() call.

Dan

Did you tried IssueService? This is what I do within my listeners. There you have to use IssueInputParameters with validateUpdate (for system and custom fields).

I have just tried with IssueService. This is my code:

IssueInputParameters issueInputParameters = issueService.newIssueInputParameters();
issueInputParameters.setSummary("this is a setSummary test!");
		 
IssueService.UpdateValidationResult updateValidationResult = issueService.validateUpdate(user, issue.getId(), issueInputParameters);
if (updateValidationResult.isValid()) 
   IssueService.IssueResult updateResult = issueService.update(user, updateValidationResult);

The thing is that the history is modified corectly but not the summary field itself. This is strange. Is something missing? Is this what you usually do or have I done something wrong? Thank you Henning.

After calling validateUpdate and update, check if there are any errors in the result. The errors, if any, will not be shown in the logs but will be in the errorCollection returned in the response object.

Hi Jobin,

Thank you for your answer.

I have just checked this. This is my code:

IssueInputParameters issueInputParameters = issueService.newIssueInputParameters();
		 issueInputParameters.setSummary("this is a setSummary test!");
		 
		 IssueService.UpdateValidationResult updateValidationResult = issueService.validateUpdate(user, issue.getId(), issueInputParameters);
		 
		 boolean updateValidationResultHasAnyErrors = updateValidationResult.getErrorCollection().hasAnyErrors();
		 System.out.println("updateValidationResultHasAnyErrors: " + updateValidationResultHasAnyErrors);	
		 
		 if (updateValidationResult.isValid()) 
		 {
			 IssueService.IssueResult updateResult = issueService.update(user, updateValidationResult);
			 boolean updateResultHasAnyErrors = updateResult.getErrorCollection().hasAnyErrors();
			 System.out.println("updateResultHasAnyErrors: " + updateResultHasAnyErrors);
		 }

Both flags updateValidationResultHasAnyErrors and updateResultHasAnyErrors are always false. It seems there are no errors in the errorCollection(s).

Also, if there was an error I think the history would not have been updated. And this is the strange thing, the history is updated but not the content of the field itself.

Thank you, Dan

I don't have any idea what this could be. My listner source is nearly the same as yours, but for testing if everything is ok I both times use isValid() on the returned object.

Maybe an index issue? If you update the issue manually after your listener seems to update it, is the summary field the same? Displays the issue navigator the same value as the detail view of the issue?

I've just tried with isValid() for both results and it return true in both cases.

I have discovered something interesting doing what you've suggested. My listener is called for pretty much any event. I have the problem described above when the listener is called for an event triggered by a workflow transition. If I just do edit of another field just to trigger ISSUE_UPDATED_ID event, then my Summary field is updated by my listener. But the new value is displayed only in the detailed view of the issue. In the issue navigator I keep having the old value... Also, my development instance of Jira starts to work very very slowly which might suggest an indexing problem. If I perform an indexation, then both issue navigator and the detail view of the issue display the same summary (that is the one set by my listener).

So it seems somehow that this modification of the summary is not done when triggered by a workflow transition. And if triggered by another event which does not imply an workflow transition (ex: ISSUE_UPDATED_ID), it leaves my jira instance in an inconsistent state.

Any idea why this is happening? Have you managed to modify successfully a system field in a listener triggered by a workflow transition? Also, i still don't understand why the approach based on issueManager.updateIssue does not work. It works in post-functions but not in listeners which I thought were executed in the same thread.

Thank you for your help Henning.

Is there the summary field on the issue transition screen if your listener is triggered by a workflow transition?

Within my listener a reindex is happening after the modifications. Make sure to use the modified issue (updateResult.getIssue()) for calling reindex.

boolean wasIndexing = ImportUtils.isIndexIssues();
ImportUtils.setIndexIssues(true);
issueIndexManager.reIndex(updateResult.getIssue());
ImportUtils.setIndexIssues(wasIndexing);

setIndexIssues() is deprecated but I still use it.

Henning,

Thank you again for your answer.

No, there was no summary field on the issue transition screen. In fact there was no issue transition screen. I have just made a test now with an issue transition screen (displaying the Summary field). After the transition the issue will have the value that I set in this screen. Again, only the history is modified with the value set by the listener, but not the summary field itself. The summary field itself has whatever I write in the transition screen.

I have just noticed that the solution that I have first proposed based on MutableIssue and issueManager.updateIssue works fine for events like ISSUE_UPDATED_ID which don't imply a workflow transition (when I do an edit for instance). Moreover there is no problem with the indexing. So it's preferable to use this solution in this case as it's taking care of the indexing problem directly.

The problem with the system field update not being done arrises only when the listener is called during a workflow transition. Then, nothing seems to work in order to modify a system field like the summary.

Henning, does your listener manage to modify a system field when triggered by a workflow transition?

Thank you for you time, Dan

Yes, I modify the fix versions (and some custom fields) through a listener triggered by issue updates and workflow transitions. I have no idea why this doesn't work for you.

I've just tested again and in my case too it works fine for fix versions and for any custom field. But it does not work for fields like Summary or Description. It seems there is a problem with these fields in particular...

I'm wondering if someone has ever managed to modify these in a listener triggered by a workflow transition.

Thank you Henning.

It should be the screen. IssueService updates the fields only if it is on screen. You might have fixVersion on the screen!

No, fixVersion was not on the screen and yet was modified. Summary was on the screen but it was not modified...

Now, the latest test I was doing was this:

mutableIssue.setSummary("this is a setSummary test!");
		 mutableIssue.setCustomFieldValue(myCustomField, "this is a setCustomField test!");
		 Collection<Version> versions = new Vector<Version>();
		 mutableIssue.setFixVersions(versions);
		 issueManager.updateIssue(user, mutableIssue, com.atlassian.jira.event.type.EventDispatchOption.DO_NOT_DISPATCH, false);

There is no transition screen (Transition View: None - it will happen instantly). Initially the issue has some fixVersion set. When i do a workflow transition that triggers the listener, the custom field is set correctly, the fixVersion is cleared as expected but the Summary is not modified.

If i do an edit and not an workflow transition, then all the fields are correctly set, Summary included.

I've tried exactly the same test case with IssueService and exactly the same happens. This was the code:

		 IssueInputParameters issueInputParameters = issueService.newIssueInputParameters();
		 issueInputParameters.setSummary("this is a setSummary test!");
		 issueInputParameters.setFixVersionIds();
		 issueInputParameters.addCustomFieldValue(myCustomField.getId(), "this is a setCustomField test!");
IssueService.UpdateValidationResult updateValidationResult = issueService.validateUpdate(user, issue.getId(), issueInputParameters); if (updateValidationResult.isValid()) { IssueService.IssueResult updateResult = issueService.update(user, updateValidationResult); if (updateResult.isValid()) System.out.println("VALID BOTH TIMES!"); }

Both results are valid (VALID BOTH TIMES! is displayed every time). When triggered by an edit all the fields are updated. When triggered by an workflow transition, Summary is not modified, only the history. It does not matter if there is a transition screen or not.

Thank you Jobin.

Hi,

I have similar problem with updates and it was caused by another listener watching the same event, running after mine and overwriting my changes back to default values.

Please check that you have only one listener to given event - in my case it was build-in Atlassian Autowatch listener (added to JIRA since 5.0.3) - for more info look here.

Pavla

Hi Pavla,

Thank you for your answer.

Yes, i have exactly the same problem as described in the link you have provided. The history is updated ok but the value of the field is not changed.

The thing is that I've just made one more test with "Autowatch" disabled for my user, and the problem is still there. The summary is not changed, the history is update correctly.

Do you think this problem is caused by "Autowatch" even if the option is disabled for the user? In your case, does the update work when the option is disabled?

Thank you,

Dan

For me it works when I disabled Autowatch in general (JIRA 5.2.2 in Administration - Users - User Preferences).

You can try to look into your database log, if there is something else changing the issue. In my case it looks like this (some rows are skipped and comments added):

// Issue created
INSERT INTO JIRAISSUE VALUES(10103,'PROJ-5',10000,'admin',NULL,'1','My new issue',NULL,NULL,'3',NULL,'1','2013-01-22 12:32:55.547000000','2013-01-22 12:32:55.547000000',NULL,NULL,0,0,NULL,NULL,NULL,10103,NULL,NULL,NULL)
// Issue changed by my listener - assignee changed from NULL to dev
DELETE FROM JIRAISSUE WHERE ID=10103
INSERT INTO JIRAISSUE VALUES(10103,'PROJ-5',10000,'admin','dev','1','My new issue',NULL,NULL,'3',NULL,'1','2013-01-22 12:32:55.547000000','2013-01-22 12:32:55.671000000',NULL,NULL,0,0,NULL,NULL,NULL,10103,NULL,NULL,NULL)
// Something changed it back to null
DELETE FROM JIRAISSUE WHERE ID=10103
INSERT INTO JIRAISSUE VALUES(10103,'PROJ-5',10000,'admin',NULL,'1','My new issue',NULL,NULL,'3',NULL,'1','2013-01-22 12:32:55.547000000','2013-01-22 12:32:55.547000000',NULL,NULL,0,1,NULL,NULL,NULL,10103,NULL,NULL,NULL)

Now i searched, what was changed in third insert (other listener) in compare to first one (issue created). It was only one number - column 17 changed from 0 to 1. This is number of watchers, so I searched what can add watchers in JIRA and it was the Autowatcher module.

Thank you Pavla for your answer. In the meanwhile an answer was provided (see above). Now it works and at least for the Summary field it does not seem to be related to the Autowatch.

I see, this over-typing solution works also for me (and better). Thanks for it :)

Is there the summary field on the issue transition screen if your listener is triggered by a workflow transition?

Within my listener a reindex is happening after the modifications. Make sure to use the modified issue (updateResult.getIssue()) for calling reindex.

boolean wasIndexing = ImportUtils.isIndexIssues();
ImportUtils.setIndexIssues(true);
issueIndexManager.reIndex(updateResult.getIssue());
ImportUtils.setIndexIssues(wasIndexing);

setIndexIssues() is deprecated but I still use it.

Yes, I modify the fix versions (and some custom fields) through a listener triggered by issue updates and workflow transitions. I have no idea why this doesn't work for you.

Hi Dan,

I am facing same problem, have you find any solution or workaround for the problem?

thanks

Hello,

No, no clean solution yet. I have poked atlassian weeks ago but nothing. I was thinking to raise this in an support issue but for now I can still work in my implementations with custom fields. So this is the workaround... use custom fields which can be changed by listeners.

If you manage to find an answer to this problem, please poste it here too.

Thanks,

Dan

I had a similar issue trying to update assignee for an issue in a workflow transition post-function. The problem was that i didn't change the order of my post-function and assignee was updated by other post-function which was executed next. Despite that the original question mentions problem with issue listener, I hope this info will help somebody.

Henning's note at https://answers.atlassian.com/questions/111666 made it work for me:

 

reIndexIssue(updateResult.getIssue());

Example of code without ancient MutableIssue:

CustomField csUserField = ComponentAccessor.getCustomFieldManager().getCustomFieldObjectByName(fieldName);
IssueService issueService = ComponentAccessor.getIssueService();
IssueInputParameters issueInputParameters = issueService.newIssueInputParameters();
issueInputParameters.addCustomFieldValue(csUserField.getId(), value_string);
issueInputParameters.setSkipScreenCheck(true);
issueInputParameters.setRetainExistingValuesWhenParameterNotProvided(true, true);
UpdateValidationResult updateValidationResult = issueService.validateUpdate(user, issue.getId(), issueInputParameters);
if (updateValidationResult.isValid())
{
    IssueResult updateResult = issueService.update(user, updateValidationResult);
    if (!updateResult.isValid())
    {
        log.warn("ISSUE has NOT been updated. Errors: {}\n", updateResult.getErrorCollection().toString());
    }
    else
    {
        log.warn("ISSUE has been updated.\n");
    }
}
else
{
    log.warn("ISSUE has NOT been updated. Errors: {}\n", updateResult.getErrorCollection().toString());
}

Hello All - In my case, I have issue updating a custom field in the JIRA issue.  After the issueUpdate() is executed, either:

1.  The new updated value won't show in the custom field until the issue is updated.

2. Everything works one day, but the other day, value not shown till the issue is updated, like #1.

In my environment, I have a event listener listening for a change in the  FixVersion field in an issue in project A.  Then based on the changes, I will query issues in project B based on the changed FixVersion, and for each issue, update the custom field.  The code is as follows.  Please let me know where the issue is.  Thanks.

CustomFieldManager customFieldManager = ComponentAccessor.getCustomFieldManager();
CustomField customField = customFieldManager.getCustomFieldObject(CUSTOM_FIELD);
MutableIssue currentMutableIssue = (MutableIssue)issue;
currentMutableIssue.setCustomFieldValue(customField, valueToSave);
ApplicationUser user = ComponentAccessor.getUserManager().getUserByName("admin");
issueManager.updateIssue(ApplicationUsers.toDirectoryUser(user), currentMutableIssue, EventDispatchOption.ISSUE_UPDATED, false);

Hi Gil,

I would suggest to create a new question for this (maybe with a link to this question) including your Jira version used and the complete source of the listener. For me the source excerpt didn't match your description (where does "issue" come from?).

Henning

Hi Henning - I think I found the issue - the code is all correct.  It's all about the timing of when the issue index occurs.  Because of this, the data I get from the issue is incorrect.

Suggest an answer

Log in or Sign up to answer
Community showcase
Published in Off-topic

Atlassian Community Guide to A+ Articles

Stop: Articles and permission Article-writing permissions are given to Leaders, Marketplace Vendors, Solutions Partners, Atlassian Team members, and those who are Level 4 + above. But for any aspir...

93 views 9 11
Read article

Community Events

Connect with like-minded Atlassian users at free events near you!

Find an event

Connect with like-minded Atlassian users at free events near you!

Unfortunately there are no Community Events near you at the moment.

Host an event

You're one step closer to meeting fellow Atlassian users at your local event. Learn more about Community Events

Events near you