Through the API how do we load child items?

We have access to PSItem but our child property which is a sys_table is not listed in the fields list. How do we load in the children? We are attempting to load in a poll which has question and answer child pairs. When trying to use the API our fields aren’t available with PSItem. And we can’t find anything in the javadocs to help. We’re also having similar issues with multi-value checkboxes.

The answer depends, in part, on which API you are using.

Since you say that you’re using PSItem, I’ll assume that you’re using Web Services. In the Java API the corresponding class is called PSCoreItem.

There are 2 different ways to access Child Tables in the WS API. One way is to request the child items be loaded when you created the LoadItemsRequest object. There’s a flag for “includeChildren” and a way to set a list of child table names. If you don’t include this, you will not get any child table entries when you load the item.

Assuming you did this properly, the child entries for an item can be accessed from PSItem.getChildren().

The other way to access the child entries is to load them separately, using Content.loadChildEntries(). This method returns an array of PSChildEntry objects, each of which contains an array of PSField objects.

You modify the child entries by setting the “action” flag on the child entry to one of (insert, update, delete, ignore). This is explained in the Web Services client’s JavaDoc.

If you loaded the child entries with the item, the call to Content.saveItems() will save the child entries along with the item. If you loaded them separately, you should call Content.saveChildEntries() directly.

If I’m incorrect in my assumption (and you are really using the Java API), let me know, and I’ll explain that API further. The principles are the same, but some of the classes and methods have different names. It is also possible to access child entries for the “JCR Node” (which can be accessed from both Java and JEXL/Velocity, but NOT Web Services). The structure of these calls is somewhat different from the PSItem/PSCoreItem approach. If you can clarify which environment you are working in, I can give you a better answer.

Dave

Thank you. I am using the web service API. Your suggestion got the child field loaded as I needed. But when I populate with the child entries and their fields, on calling saveItems an org.apache.commons.beanutils.ConversionException occurs. The PSItem looks EXACTLY like one that already exists in Rhythmyx and which I loaded through my code to confirm.

Is this not the right way to save:
SaveItemsRequest req = new SaveItemsRequest();
req.setPSItem(new PSItem[]{item});
SaveItemsResponse response = getContentService().saveItems(req);

The same error happens when using the SaveChildEntriesRequest. Any further advice?

The way I usually do it is:

SaveItemsRequest req = new SaveItemsRequest(new PSItem[]{item},false,false);
SaveItemsResponse response = getContentService().saveItems(req);

But I don’t see why your way doesn’t work.

However, I"m wondering if you are trying to save a new item with child entries. I don’t believe that this is allowed: you have to create the item (and save it) before adding the child entries.

Dave

Dave is correct. Rhythmyx does not allow you to create a Content Item with children in one step. You must create the Content Item (or “parent” Content Item"), save it, then add the child content to it.

See “Creating a Content Item with Children” on p. 7 of the Rhythmyx Web Services Development Kit.

I was aware that the item needs to be created first and am doing that. The PDF referenced was useful but unfortunately it looks like I am doing what I should be doing. Or am I wrong?

Without attaching the full code here are the steps:
The item is created.
A search by sys_title is done to retrieve the created item. Get the Id from it.
Prepare the item for editing based on the Id retrieved from the search result.
Load the child items onto the item.
Do the save items request.
Release the item from edit.

I’ll try another way this time around to see if I get any different behavior.

One question (and a suggestion).

When you “load” the item, do you load it with the children, or do you load them later on?

If you are loading the children separately from the item, you should save them separately as well.

If you are loading them together with the item, you can modify the array and save them with the item.

Dave

Here is the code, literally though extracted out from helper methods. If nothing looks wrong here then it is either how I’m populating the children in the code or how we created the table template.

PSItemStatus itemStatus = getContentService().prepareForEdit(new long[] {id})[0];

LoadItemsRequest req = new LoadItemsRequest();
req.setId(new long[]{id});
req.setIncludeBinary(true);
req.setAttachBinaries(true);
req.setIncludeChildren(true);
req.setChildName(new String[] { childName });
PSItem[] items = getContentService().loadItems(req);
PSItem contentItem = items[0];

setTableChildren(contentItem, childTableName, entries); // this populates the children

SaveItemsRequest req = new SaveItemsRequest();
req.setPSItem(new PSItem[]{item});
getContentService().saveItems(req);

ReleaseFromEditRequest req = new ReleaseFromEditRequest();
req.setPSItemStatus(new PSItemStatus[] {status});
getContentService().releaseFromEdit(req);

The code looks reasonable to me.

Let’s go back and focus on the error you are getting. A ConversionException usually means something is the wrong type of object. I notice that you are including Binaries. Do you need the binaries? If not, I’d suggest starting by turning that flag off.

Which application does the conversion exception occur in? Is it in your application, or the Rhythmyx server?

If the operation is getting as far as the Rhythmyx server, there may be some hints in the server log. Have you looked there? (Sometimes the log is less than useful, but it can provide clues to where the operation is going off track).

Can you also please post the code for the setTableChildren(contentItem, childTableName, entries) method? Also, where does the value for the “entries” param come from, and what is “childTableName” and how does it differ from the “childName” value you supply to req.setChildName() ?

I finally got this working last night by rewriting the code. I had to create child entries, load my data into the entries returned from that call, then save them. Here’s my dummy test code. I don’t like it but it worked so I’ll keep going with this and implement my actual loading of the entries. Thanks for the help.

Long contentIdNum = contentId;
PSItemStatus itemStatus = prepareForEdit(contentIdNum);
CreateChildEntriesRequest req = new CreateChildEntriesRequest();
req.setId(contentIdNum);
req.setCount(1);
req.setName(“questions”);
PSChildEntry[] entries = getContentService().createChildEntries(req);

PSChildEntry entry = entries[0];
PSField[] entryFields = entry.getPSField();
int count = 0;
for (PSField entryField : entryFields)
{
PSFieldValue[] fieldValueArray = entryField.getPSFieldValue();
if (ArrayUtils.isEmpty(fieldValueArray))
{
fieldValueArray = new PSFieldValue[1];
}
PSFieldValue value = new PSFieldValue();
value.setRawData(“RawData”);
fieldValueArray[0] = value;
entryField.setPSFieldValue(fieldValueArray);
entry.setPSField(count, entryField);
}
entries[0] = entry;

SaveChildEntriesRequest saveReq = new SaveChildEntriesRequest();
saveReq.setPSChildEntry(entries);
saveReq.setId(contentIdNum);
saveReq.setName(“questions”);
getContentService().saveChildEntries(saveReq);

releaseFromEdit(itemStatus);

I have a related question which is giving me grief:

This approach works for genuine child table entries, but doesn’t seem to cater for “simpleChild” fieldsets, e.g. Multiselect drop-downs or checkboxtrees. Nor does simply saving the data (semi-colon separated) into the field, as it stores separators and all rather than splitting it out.

There seems to be no guidance on specific case in the WSDK PDF document, or am I just missing a trick?

thanks,

Oliver

Example case:
Multiple selectbox field: categories,
denoted by a simpleChild fieldset: categories_set

Oliver,

The “simple child”, is not really a “child”, it’s more like a multi-value field.

You write it by creating an array of PSFieldValue objects, each of which contains one value.

Dave

Thanks Dave,

you’re right of course, and it works a treat.

Thanks for that

O