Direct field update triggers another field update does not work.

Hello,

I have two custom fields (both Insight fields). When I update customfield1, a listener also updates the value of customfield2 according to customfield1 value. This works fine when I click the "Edit" button, but does not work when I edit directly on the issue. I have checked, the listener is properly called in both cases, it just seems not to commit in some way in the second case.

Here is what my script looks like : 

def customFieldManager = ComponentAccessor.getCustomFieldManager()

def customfield_1_Changed = event?.getChangeLog()?.getRelated("ChildChangeItem")?.find {it.field == "Customfield_1"}
if (customfield_1_Changed){
   def customfield_2_value = SomeMethodThatGivesTheValue()
   def customfield_2 = 
   customFieldManager.getCustomFieldObject("customfield_2")
   customfield_2.updateValue(null, issue, new ModifiedValue(null, 
   customfield_2_value), new DefaultIssueChangeHolder())
   def issueIndexingService = 
   ComponentAccessor.getComponent(IssueIndexingService)
   issue.store()
   issueIndexingService.reIndex(issue)
}

4 answers

Hey, any insight on this issue ?

I have been able to resolve this Issue by puting a log around the code block supposed to automatically modify the custom fields values. It is not the first time puting a log solves the issue, it is a really weird and constraining behaviour.

Nevermind, it worked only once. Still need help on this.

0 vote

Hi Antoine,

The same issue updated event is fired and handled when doing the inline edit and when you bring the edit screen up.

I suspect it's because your doing the reindexing and storing the issue in the database manually.

The best way of updating a custom field on an issue is to use IssueService as it will do the saving and reindexing for you as well as show you what errors prevented the update from happening if any.

The example below copies the value of custom field 1 to custom field 2 (assuming both are text fields) if custom field 1 has changed.

import com.atlassian.jira.component.ComponentAccessor
import com.atlassian.jira.event.issue.IssueEvent

def event = event as IssueEvent

def customFieldManager = ComponentAccessor.getCustomFieldManager()
def issueService = ComponentAccessor.getIssueService()

def customFieldChanged = event?.getChangeLog()?.getRelated("ChildChangeItem")?.find {it.field == "Customfield_1"}

if (customFieldChanged) {
    def customField1 = customFieldManager.getCustomFieldObject("customfield_1")
    def customField2 = customFieldManager.getCustomFieldObject("customfield_2")
    def customField1Value = customField1.getValue(event.issue)

    def issueInputParameters = issueService.newIssueInputParameters()

    issueInputParameters.addCustomFieldValue(customField2.idAsLong, customField1Value)

    def validationResult = issueService.validateUpdate(event.user, event.issue.id, issueInputParameters)

    if (validationResult.isValid()) {
        issueService.update(event.user, validationResult)
    } else {
        log.warn "Did not update issue: $validationResult.errorCollection.errors"
    }
}

Let us know how you get on after you have used issue service in your listener.

 Thanks,
Adam

Hi Adam, thanks for your reply. I have a problem while updating the field : 

issueInputParameters.addCustomFieldValue(customField2.idAsLong, customField1Value)

only works for String values. Mine is an ArrayList<MutableObjectBean> (I am working with Insight), so I cannot make this work. 

Thanks for that I understand now. It may be worth contacting the vendor for the Insight plugin and seeing if they can give you any pointers here.

There may be some caveats with this type of field when you do the inline edit which is preventing the field from being updated if it works on the edit screen. For the event listener there should be no difference between the two.

Unfortunately we don't have any specific examples of updating that type of custom field.

For regular JIRA custom fields the way I've pointed out is the best way to update them.

Thanks for your quick feedback. Does that work even for non string customfields? Like list, checkbox or number (Since the custom field value is not directly a string)

If it's a list or checkbox you should put the option id in as a string.

For multiselects you can pass in multiple option ids:

issueInputParameters.addCustomFieldValue(customField.idAsLong, "1", "2")

For numbers you just need to pass them in as a string.

Every JIRA custom field type you can update in this way as JIRA uses IssueService underneath.

Hope this clears things up for you.

Hehe... I tried with the insight unique object code and it worked! My problem is with your method I need to use event. I am using a lot of classes for different functions and I am going through at least 3 classes to update this field... Is there a way to get the event from the Issue object (or in any kind of way which does not imply to put it as a function paramater) ?
Thanks!

That's good to hear I was wondering if that would work.

You could have a common function which it sounds like you have already. The only event-centric things are where we get the issue and the current user from.

If you don't have an event you can use the following to get the current user (note that the user must have edit permissions):

import com.atlassian.jira.component.ComponentAccessor

def user = ComponentAccessor.getJiraAuthenticationContext().loggedInUser

The issue is already available in most places in ScriptRunner so you can just use it as is.

Hope this helps.

You are absolutely right, I did not pay enough attention, my bad...
I guess i have to re-write my functions now, but I guess it is worth it. One last thing I want to be sure of, does the code trigger the Issue update event as is ? (I need the notification to be sent)
Thanks!

Yes that will trigger the issue updated event and also send mail, as if the issue was updated by that user in JIRA.

Wow, thanks for everything and your quick answers. Cheers

Quick update. The code works, but it usually throws (I did not identify a specific pattern causing the error) this exception : java.util.concurrentmodificationexception on this call : 

issueService.update(user, validationResult)

 Have you already encountered this issue ? I can provide the full stacktrace if needed.

@Adam Markham [Adaptavist] I had to first clear the custom field not to get the error : 

issueObject.setCustomFieldValue(myCustomField, null)
issueManager.updateIssue(user, issue, EventDispatchOption.ISSUE_UPDATED ,true)

 Can you confirm this is the right behaviour ?

@Adam Markham [Adaptavist] I have noticed that this method works only if the field is displayed on the same screen when the field update occurs. This is really problematic because we use some fields which are not displayed directly on the issue on our boards / filters... Any idea?

@Antoine Berry I have not seen that before. It must be something specific to do with the Insight custom field. You may get a solution if you contact the vendor directly.

Do you see the same error for a regular JIRA custom field when updating it via this method?

@Adam Markham [Adaptavist] I have used this method only with Insight custom field, so no. I guess it is linked to the insight custom field somehow, I will come back here if I notice that for a regular custom field.

Hi Adam, thanks for your reply. I have a problem while updating the field : 

issueInputParameters.addCustomFieldValue(customField2.idAsLong, customField1Value)

only works for String values. Mine is an ArrayList<MutableObjectBean> (I am working with Insight), so I cannot make this work. 

Sorry for the double answer, my answer could not be validated when i added code block...

@Antoine Berry and @Adam Markham [Adaptavist] sorry for the spam filter's over-excitement. I've released your comments from the quarantine. 

Suggest an answer

Log in or Sign up to answer
How to earn badges on the Atlassian Community

How to earn badges on the Atlassian Community

Badges are a great way to show off community activity, whether you’re a newbie or a Champion.

Learn more
Community showcase
Published Jul 10, 2018 in Marketplace Apps

If you’re an Atlassian app developer, you’ll want to know about Atlas Camp!

This September 6-7, hundreds of Atlassian App developers will flock to Barcelona Spain to build skills, discover product roadmaps, meet face-to-face with the Atlassian team, and learn how to extend t...

176 views 0 4
Read article

Atlassian User Groups

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

Find a group

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

Find my local user group

Unfortunately there are no AUG chapters near you at the moment.

Start an AUG

You're one step closer to meeting fellow Atlassian users at your local meet up. Learn more about AUGs

Groups near you