I have a lot of classes that are converted to XML using eclipse MOXy @XmlNamedObjectGraphs to generate. They mostly seem to behave themselves, except for one class - TaskSchedule:
@XmlAccessorType(XmlAccessType.PROPERTY)
@XmlNamedObjectGraphs({
@XmlNamedObjectGraph(
name="full",
attributeNodes = {
@XmlNamedAttributeNode( "businessEntityNumber" ),
@XmlNamedAttributeNode( "businessEntityClass" ),
@XmlNamedAttributeNode( value="task", subgraph="simple" ),
@XmlNamedAttributeNode( "cron" ),
@XmlNamedAttributeNode( "enabled" ),
@XmlNamedAttributeNode( "endDate" ),
@XmlNamedAttributeNode( "name" ),
@XmlNamedAttributeNode( "period" ),
@XmlNamedAttributeNode( value="region", subgraph="simple" ),
@XmlNamedAttributeNode( value="productGroup", subgraph="simple" ),
@XmlNamedAttributeNode( value="user", subgraph="simple" ),
@XmlNamedAttributeNode( "scheduleType" ),
@XmlNamedAttributeNode( "startDate" ),
@XmlNamedAttributeNode( value="parameterGroup", subgraph="full" )
}),
@XmlNamedObjectGraph(
name="simple",
attributeNodes = {
@XmlNamedAttributeNode( "businessEntityNumber" ),
@XmlNamedAttributeNode( "businessEntityClass" ),
@XmlNamedAttributeNode( "name" )
}),
@XmlNamedObjectGraph(
name="child_group", // used when as a child of a group - some fields dont apply
attributeNodes = {
@XmlNamedAttributeNode( "businessEntityNumber" ),
@XmlNamedAttributeNode( "businessEntityClass" ),
@XmlNamedAttributeNode( "name" ),
@XmlNamedAttributeNode( value="region", subgraph="simple" ),
@XmlNamedAttributeNode( value="productGroup", subgraph="simple" ),
@XmlNamedAttributeNode( value="task", subgraph="simple" ),
@XmlNamedAttributeNode( value="parameterGroup", subgraph="full" )
})
})
public class TaskSchedule extends AbstractBusinessEntity {
protected Task task;
protected String cron;
protected Boolean enabled;
protected Date endDate;
protected String name;
protected ExecutionPeriod period;
protected Region region;
protected ProductGroup productGroup;
protected TaskScheduleType scheduleType;
protected Date startDate;
protected TaskParameterGroup parameterGroup;
protected User user;
// get/set methods
}
Things work OK when I convert the schedule to XML, if that schedule is the top-level element to be converted (ie the 'full' graph is used). However I also have other classes - TaskGroup and TaskGroupSchedule:
@XmlAccessorType(XmlAccessType.PROPERTY)
@XmlNamedObjectGraphs({
@XmlNamedObjectGraph(
name="full",
attributeNodes = {
@XmlNamedAttributeNode( "businessEntityNumber" ),
@XmlNamedAttributeNode( "businessEntityClass" ),
@XmlNamedAttributeNode( "name" ),
@XmlNamedAttributeNode( value="createdBy", subgraph="simple" ),
@XmlNamedAttributeNode( "createdOn" ),
@XmlNamedAttributeNode( value="schedules", subgraph="simple" ),
}
),
@XmlNamedObjectGraph(
name="simple",
attributeNodes = {
@XmlNamedAttributeNode( "businessEntityNumber" ),
@XmlNamedAttributeNode( "businessEntityClass" ),
@XmlNamedAttributeNode( "name" )
}
)
})
public class TaskGroup extends AbstractBusinessEntity {
protected String name;
protected User createdBy;
protected Date createdOn;
protected Set<TaskGroupSchedule> schedules;
// get/set methods
}
TaskGroupSchedule:
@XmlAccessorType(XmlAccessType.PROPERTY)
@XmlNamedObjectGraphs({
@XmlNamedObjectGraph(
name="child",
attributeNodes = {
@XmlNamedAttributeNode( "id" ),
@XmlNamedAttributeNode( "className" ),
@XmlNamedAttributeNode( value="schedule", subgraph="child_group" ),
@XmlNamedAttributeNode( "sequence" ),
@XmlNamedAttributeNode( "enabled" ),
@XmlNamedAttributeNode( "stopOnError" ),
@XmlNamedAttributeNode( "delayBeforeNext" ),
})
})
public class TaskGroupSchedule extends AbstractManagedData implements IEnableable, IRegional, Sequenceable {
protected TaskGroup parent;
protected TaskSchedule schedule;
protected int sequence;
protected Boolean enabled;
protected long delayBeforeNext;
// get/set methods, with @XMLTransient on getParent
}
Heres the problem: When I try to convert a TaskGroup to XML, it ignores my request to use the 'child_group' subgraph for TaskGroupSchedule -> TaskSchedule and instead goes through every single property of TaskSchedule, converting them (leading to unexpected 'A cycle is detected in the object graph. This will cause infinitely deep XML' errors for items with references back to the parent), which I'm guessing is default behavior if there is no graph defined. Im using MOXy version 2.6.3 and Java 8.
Can anyone see what I'm doing wrong? Thanks in advance.
OK I missed an obvious problem.
It was because the
TaskGroup
graph assumed that theTaskGroupSchedule
had a'simple'
graph defined not a'child'
graph. Changing'simple'
to'child'
in TaskGroup made it work.