0

We have a very large object graph (lazy loaded from the DB via DataNucleus ORM during normal program execution so no problem normally) but we only want to serialize a small portion of it with SnakeYaml - just a small subset of classes.

There is a relationship from one of these classes to other classes which end up "reaching" most of the other objects in the object graph which results in pulling nearly all objects from the database into the YAML serialization stream - the classic "serializing the whole world" problem which doesn't end well when you have millions of reachable objects as you can imagine :)

I found the SnakeYaml 'Representer' class which appears like a hook that lets you specify "not" to serialize a particular bean but it appears like it doesn't act like a circuit breaker on the object graph navigation process when it encounters that bean. It won't write YAML output for that bean but SnakeYaml appears to continue navigating the object graph past that bean.

private class CircuitBreakerRepresenter extends Representer
{

    @Override
    protected NodeTuple representJavaBeanProperty(Object javaBean, Property property,
                                                  Object propertyValue, Tag customTag) {

        // Intention: Don't navigate past the instances of 'Role' class when serializing
        // Outcome: Appears to continue navigating past 'Role' class instances
        if (javaBean instanceof Role) {
            return null;
        } else {
            return super.representJavaBeanProperty(javaBean, property, propertyValue,
                customTag);
        }
    }
}

Is there a way to cause SnakeYaml to not navigate past a particular bean when serializing an object graph?

Volksman
  • 1,969
  • 23
  • 18

1 Answers1

1

I just managed to answer my own question :)

What I was doing wrong was attempting to stop the object graph navigation at the class level.

What you need to do to circuit break the navigation is do it at the level of the individual relationship/property that you don't want SnakeYaml to navigate beyond during serialization.

so instead of

if (javaBean instanceof Role) {
    return null;

I needed to do

if (javaBean instanceof ClassWithAttribute && property.getName().equals("classAttributeName"))
    return null;

where:

  • "ClassWithAttribute" is the name of the class with the relationship beyond which you don't want the serialization to proceed.
  • "classAttributeName" is the name of the relationship attribute beyond which you don't want the serialization to proceed.
Volksman
  • 1,969
  • 23
  • 18