Set Portfolio 'Parent Link' field value using ScriptRunner

Rob_Duncan May 29, 2018

On a workflow transition I need to check that a parent issue has children with the Portfolio 'Parent Link' field which appears to work:

cfValues['Parent Link'] == null

 

However in creating the new child issue I am unable to set the 

def cf = customFieldManager.getCustomFieldObjects(sourceIssue).find {it.name == 'Parent Link'}
issue.setCustomFieldValue(cf, sourceIssue.key)

 

The following error is returned:

2018-05-29 07:47:17,418 ERROR [workflow.ScriptWorkflowFunction]: Script function failed on issue: EPIC-42, actionId: 81, file: null
groovy.lang.MissingPropertyException: No such property: Key for class: com.atlassian.jira.issue.IssueImpl
Possible solutions: key, id
at Script346.run(Script346.groovy:6)

 

4 answers

2 accepted

4 votes
Answer accepted
Olivier MOREAU May 26, 2020

Dear all,

I have developed the following code and it seems to work in latest versions of 2020:

import com.atlassian.jira.issue.MutableIssue
import com.atlassian.jira.event.type.EventDispatchOption
import com.atlassian.jira.user.ApplicationUser
import com.atlassian.jira.security.JiraAuthenticationContext
import com.atlassian.jira.issue.MutableIssue
import com.atlassian.jira.event.issue.IssueEvent
import com.atlassian.jira.bc.issue.IssueService
import com.atlassian.jira.issue.customfields.manager.OptionsManager
import com.atlassian.jira.issue.customfields.option.Options
import com.atlassian.jira.issue.ModifiedValue
import com.atlassian.jira.issue.util.DefaultIssueChangeHolder

public static createParentLink(Issue parentIssue, Issue childIssue) {
def issueManager = ComponentAccessor.getIssueManager()
def customFieldManager = ComponentAccessor.getCustomFieldManager()
def parentLinkField = customFieldManager.getCustomFieldObjectByName("Parent Link")
def parentLinkFieldType = parentLinkField.getCustomFieldType()

JiraAuthenticationContext jiraAuthenticationContext = ComponentAccessor.getJiraAuthenticationContext();
ApplicationUser user = jiraAuthenticationContext.getUser();

def mutableParentIssue = parentLinkFieldType.getSingularObjectFromString(parentIssue.key)

def mutableIssue = issueManager.getIssueObject(childIssue.id)

def changeHolder = new DefaultIssueChangeHolder()
parentLinkField.updateValue(null, mutableIssue, new ModifiedValue(parentLinkField, mutableParentIssue), changeHolder)
}
1 vote
Answer accepted
Rob_Duncan May 31, 2018

I contacted Adaptivist and they confirmed my fears:

There is not a currently known way to set the value of a Parent Link field programmatically using the Java API. It's possible that there are workarounds, but we don't know them as of yet. Retrieving the information from the field is possible (we actually have some JQL functions that do that), but there's not a good known way to set it. That is why setCustomFieldValue() works for every other custom field but the Parent Link field.

Atlassian advised:

Atlassian doesn't officially offer support for development questions or help with customisation

However I might be able to point you in the right direction:

It is possible to modify data via the database.

Here is an overview of tables that is used by JIRA Applications (Portfolio is listed):
https://confluence.atlassian.com/jirakb/active-objects-ao-tables-in-jira-application-database-830279481.html

You can also use the REST API from Portfolio 
https://docs.atlassian.com/portfolio-for-jira-server/REST/2.13.0/teams/

 

So I am going to follow the proposal from this community question:

https://community.atlassian.com/t5/Marketplace-Apps-questions/Can-i-update-custom-field-value-of-Parent-Link-type-via-workflow/qaq-p/598745 

alexey_pelykh December 24, 2019

There's a way to do that:

def customFieldManager = ComponentAccessor.getCustomFieldManager()
def parentLinkField = customFieldManager.getCustomFieldObject(10200L)
def parentLinkFieldType = parentLinkField.getCustomFieldType()

def newParentLink = some issue
if (newParentLink) {
newParentLink = parentLinkFieldType.getSingularObjectFromString((newParentLink as Issue).key)
}

def mutableIssue = issueManager.getIssueObject(event.issue.id)
mutableIssue.setCustomFieldValue(parentLinkField, newParentLink)
issueManager.updateIssue(opsbot, mutableIssue, EventDispatchOption.ISSUE_UPDATED, false) 
Like # people like this
Tomasz Bryła February 20, 2020

Hello @alexey_pelykh ,

I tried your code and works perfectly in most cases, but sometimes I get this error. Additionally this problem occurring only in Live environment. In test, on exactly the same task script works.

IssueService issueService = ComponentAccessor.getIssueService()
IssueManager issueManager = ComponentAccessor.getIssueManager()
ApplicationUser user = ComponentAccessor.getUserManager().getUserByName("svc.JIRA.Automation")
OptionsManager optionsManager = ComponentAccessor.getOptionsManager()
def issue = issueManager.getIssueByCurrentKey("BCM-1891")
def newIssue = issueManager.getIssueByCurrentKey("EDSGL-25")
def linkManager = ComponentAccessor.getIssueLinkManager()
def cfm = ComponentAccessor.getCustomFieldManager()
def projectField = cfm.getCustomFieldObject(14400)
def parentLinkField = cfm.getCustomFieldObject(14001)
def parentLinkFieldType = parentLinkField.getCustomFieldType()
def searchProvider = ComponentAccessor.getComponent(SearchProvider)
def jqlQueryParser = ComponentAccessor.getComponent(JqlQueryParser)
def query = jqlQueryParser.parseQuery("issuetype = Epic AND BCM ~ ${issue.key}")
def results = searchProvider.search(query, user, PagerFilter.getUnlimitedFilter())
def parentLink
def bcmField = cfm.getCustomFieldObject(14210)
def bcmLookupField = cfm.getCustomFieldObject(13000)
def bcmFieldValue
def prjIssue
def bcmProject = (issue.getIssueType().getName() == "BCM Project")
def bcmEnhancement = (issue.getIssueType().getName() == "BCM Enhancement")
parentLink = parentLinkFieldType.getSingularObjectFromString("PRJ-81")
def issueIndexingService = ComponentAccessor.getComponent(IssueIndexingService)

newIssue.setCustomFieldValue(parentLinkField,parentLink)
issueManager.updateIssue(user, newIssue, EventDispatchOption.ISSUE_UPDATED, false)


 

2020-02-20 15:16:55,983 http-nio-8080-exec-3 ERROR Tomasz.Bryla 916x4448803x3 1ot76ru 10.33.11.250 /rest/scriptrunner/latest/user/exec/ [c.a.r.j.customfields.parent.ParentCustomFieldHelper] 
java.lang.IllegalArgumentException
 at com.google.common.base.Preconditions.checkArgument(Preconditions.java:108)
 at com.atlassian.jira.entity.property.BaseEntityPropertyService.setProperty(BaseEntityPropertyService.java:96)
 at com.atlassian.jira.entity.property.DelegatingEntityPropertyService.setProperty(DelegatingEntityPropertyService.java:41)
 at sun.reflect.GeneratedMethodAccessor2852.invoke(Unknown Source)
 at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
 at java.lang.reflect.Method.invoke(Method.java:498)
 at com.atlassian.plugin.util.ContextClassLoaderSettingInvocationHandler.invoke(ContextClassLoaderSettingInvocationHandler.java:26)
 at com.sun.proxy.$Proxy35.setProperty(Unknown Source)
 ... 2 filtered
 at java.lang.reflect.Method.invoke(Method.java:498)
 at com.atlassian.plugin.osgi.bridge.external.HostComponentFactoryBean$DynamicServiceInvocationHandler.invoke(HostComponentFactoryBean.java:136)
 at com.sun.proxy.$Proxy35.setProperty(Unknown Source)
 at com.atlassian.rm.common.bridges.jira.issue.properties.IssuePropertyServiceBridge76.setProperty(IssuePropertyServiceBridge76.java:52)
 at com.atlassian.rm.common.env.issues.JiraIssuePropertyService.setProperty(JiraIssuePropertyService.java:263)
 at com.atlassian.rm.common.env.issues.JiraIssuePropertyService.set(JiraIssuePropertyService.java:104)
 at com.atlassian.rm.jpo.customfields.parent.issue.DefaultIssueParentService.setParentId(DefaultIssueParentService.java:40)
 at com.atlassian.rm.jpo.customfields.parent.ParentCustomFieldHelper.setIssueParent(ParentCustomFieldHelper.java:97)
 at com.atlassian.rm.jpo.customfields.parent.ParentCustomFieldType.createValue(ParentCustomFieldType.java:57)
 at com.atlassian.rm.jpo.customfields.parent.ParentCustomFieldType.createValue(ParentCustomFieldType.java:17)
 at com.atlassian.jira.issue.fields.ImmutableCustomField.createValue(ImmutableCustomField.java:693)
 at com.atlassian.jira.issue.fields.ImmutableCustomField.updateValue(ImmutableCustomField.java:410)
 at com.atlassian.jira.issue.fields.ImmutableCustomField.updateValue(ImmutableCustomField.java:396)
 at com.atlassian.jira.issue.managers.DefaultIssueManager.updateFieldValues(DefaultIssueManager.java:708)
 at com.atlassian.jira.issue.managers.DefaultIssueManager.updateIssue(DefaultIssueManager.java:673)
 at com.atlassian.jira.issue.managers.DefaultIssueManager.updateIssue(DefaultIssueManager.java:659)
 at com.atlassian.jira.issue.managers.RequestCachingIssueManager.updateIssue(RequestCachingIssueManager.java:214)
 at com.atlassian.jira.issue.IssueManager$updateIssue$1.call(Unknown Source)
 at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCall(CallSiteArray.java:47)
 at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:116)
 at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:152)
 at Script842.run(Script842.groovy:55)
2 votes
Jonathan Muse _Appfire_
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.
October 17, 2018

Hi, I am the product manager for an add-on called Power Scripts that lets you create the same type of automation as Script Runner. I know this question was already answered but I just wanted to share some information that might be helpful to others who are not groovy developers and are just looking for a solution to their problem. Instead of trying to copy and paste the code you don’t understand then crossing your fingers hoping it works, there is an easier solution.

#{Parent Link} = "TEST-1234";

That's all it would take in Power Scripts and its easy enough to understand. 

Friedrich_Schlerka August 19, 2019

Where do I have to place this code. Listener ?

0 votes
Tarun Sapra
Community Leader
Community Leader
Community Leaders are connectors, ambassadors, and mentors. On the online community, they serve as thought leaders, product experts, and moderators.
May 29, 2018

Try this

issue.setCustomFieldValue(cf, ComponentAccessor.issueManager.getIssueObject(parentIssue.key))
Tarun Sapra
Community Leader
Community Leader
Community Leaders are connectors, ambassadors, and mentors. On the online community, they serve as thought leaders, product experts, and moderators.
May 29, 2018

the above snippet expects that the script is executed on the child issue i.e."issue" object and parentIssue is the issue object of the "parent" (initiative/theme)

Rob_Duncan May 31, 2018

Tarun, I tried and received this error:

groovy.lang.MissingPropertyException: No such property: Key for class: com.atlassian.jira.issue.IssueImpl
Possible solutions: key, id
 at Script346.run(Script346.groovy:6)
Luke Galardi March 20, 2020

I have received that same error as well

Suggest an answer

Log in or Sign up to answer