legacy-knowledge-base
公開されました Jun. 30, 2025

Updating Parent Object Fields from Child Object Actions

written-by

Balázs Létai

How To articles are not official guidelines or officially supported documentation. They are community-contributed content and may not always reflect the latest updates to Liferay DXP. We welcome your feedback to improve How To articles!

While we make every effort to ensure this Knowledge Base is accurate, it may not always reflect the most recent updates or official guidelines.We appreciate your understanding and encourage you to reach out with any feedback or concerns.

legacy-article

learn-legacy-article-disclaimer-text

Issue

  • How to update a field's value in the parent object when a new child instance is created using object actions of the child object.

Environment

  • Liferay DXP 7.4+

Resolution

Use a Groovy script Action triggered by onAfterAdd or onAfterUpdate on the child object to update the parent object. 

Here are two example Groovy scripts.

In the first one there is a text field 'sometext' in the parent object and its value is getting updated, every time a new child instance is created. Parent and Child objects have a one to many relationship.

In the second one there is an integer field 'numberofchildren' in the parent object and its value is getting incremented every time a new child instance is created.

1. Updating a text field in the parent object:

import com.liferay.portal.kernel.log.LogFactoryUtil
import com.liferay.portal.kernel.log.Log
import com.liferay.portal.kernel.service.ServiceContext
import com.liferay.object.model.ObjectEntry
import com.liferay.object.service.ObjectEntryLocalServiceUtil
import java.io.Serializable

Log log = LogFactoryUtil.getLog(this.class)

try {
log.info("Starting Parent update on Child creation...")

// Extract values from entryDTO["properties"]
Map<String, Object> properties = (Map<String, Object>) entryDTO.get("properties")
if (properties == null) {
log.error("No properties found in entryDTO!")
return
}

// Convert Parent ID to long
long parentEntryId = Long.parseLong((String) properties.get("r_relation_c_parentId"))
String childName = (String) properties.get("name")

log.info("Extracted Parent ID: " + parentEntryId)
log.info("Extracted Child Name: " + childName)

if (parentEntryId <= 0) {
log.error("Parent ID is invalid or missing!")
return
}

// Fetch the Parent entry
ObjectEntry parentEntry = ObjectEntryLocalServiceUtil.getObjectEntry(parentEntryId)

if (parentEntry == null) {
log.error("Parent entry not found for ID: " + parentEntryId)
return
}

log.info("Listing all Parent object fields...")
parentEntry.getValues().each { key, value ->
log.info("Field: " + key + " -> Value: " + value)
}

log.info("Parent entry found. Updating 'sometext' field...")

// Use the correct field key
String parentNameFieldKey = "sometext"

// Prepare updated values
Map<String, Serializable> values = new HashMap<>()
values.put(parentNameFieldKey, "Updated by Child: " + childName)

// Get user ID from `currentUserId`
long userId = (long) currentUserId

// Update the Parent object
ServiceContext serviceContext = new ServiceContext()
ObjectEntryLocalServiceUtil.updateObjectEntry(userId, parentEntryId, values, serviceContext)

log.info("Parent 'sometext' field update submitted successfully!")

} catch (Exception e) {
log.error("Script failed: " + e.getMessage(), e)
}

2. Updating an integer field in the parent object:

import com.liferay.portal.kernel.log.LogFactoryUtil
import com.liferay.portal.kernel.log.Log
import com.liferay.portal.kernel.service.ServiceContext
import com.liferay.object.model.ObjectEntry
import com.liferay.object.service.ObjectEntryLocalServiceUtil
import java.io.Serializable

Log log = LogFactoryUtil.getLog(this.class)

try {
log.info("Starting Parent numeric field update on Child creation...")

// Extract values from entryDTO["properties"]
Map<String, Object> properties = (Map<String, Object>) entryDTO.get("properties")
if (properties == null) {
log.error("No properties found in entryDTO!")
return
}

// Convert Parent ID to long
long parentEntryId = Long.parseLong((String) properties.get("r_relation_c_parentId"))

log.info("Extracted Parent ID: " + parentEntryId)

if (parentEntryId <= 0) {
log.error("Parent ID is invalid or missing!")
return
}

// Fetch the Parent entry
ObjectEntry parentEntry = ObjectEntryLocalServiceUtil.getObjectEntry(parentEntryId)

if (parentEntry == null) {
log.error("Parent entry not found for ID: " + parentEntryId)
return
}

log.info("Parent entry found. Fetching current numeric field value...")

// Define the numeric field key (replace with the actual field name)
String parentNumericFieldKey = "numberofchildren" // Replace with the actual numeric field name

// Get the current value and ensure it's a number
Object currentValue = parentEntry.getValues().get(parentNumericFieldKey)
int newValue = 0

if (currentValue instanceof Number) {
int currentIntValue = ((Number) currentValue).intValue()

// Check for overflow before incrementing
if (currentIntValue < Integer.MAX_VALUE) {
newValue = currentIntValue + 1
} else {
log.warn("Integer field overflow: current value is already at max.")
newValue = Integer.MAX_VALUE // Set to max value to avoid overflow
}
} else {
newValue = 1 // Start at 1 if the field is null or non-numeric
}

log.info("Current Value: " + currentValue + ", New Value: " + newValue)

// Prepare updated values
Map<String, Serializable> values = new HashMap<>()
values.put(parentNumericFieldKey, newValue)

// Get user ID from `currentUserId`
long userId = (long) currentUserId

// Update the Parent object
ServiceContext serviceContext = new ServiceContext()
ObjectEntryLocalServiceUtil.updateObjectEntry(userId, parentEntryId, values, serviceContext)

log.info("Parent numeric field '" + parentNumericFieldKey + "' updated successfully!")

} catch (Exception e) {
log.error("Script failed: " + e.getMessage(), e)
}

 

update1.gif

Additional Information

  • Remember to replace sometext and numberofchildren with the actual field keys from your Object definitions.
  • Ensure your child object has a field referencing the parent's ID (e.g., using a relationship field).
  • This approach assumes a one-to-many relationship between parent and child objects.
  • Make sure that groovy is enabled at System settings > Script management, in order to have the option at object actions.

 

 

did-this-article-resolve-your-issue

legacy-knowledge-base