Предотвращение проблемы сериализации всего мира для графа больших объектов в SnakeYaml

У нас есть очень большой граф объектов (ленивая загрузка из БД через DataNucleus ORM во время обычного выполнения программы, поэтому обычно проблем нет), но мы хотим сериализовать только небольшую его часть с помощью SnakeYaml — всего лишь небольшое подмножество классов.

Существует связь между одним из этих классов и другими классами, которые в конечном итоге «достигают» большинства других объектов в графе объектов, что приводит к извлечению почти всех объектов из базы данных в поток сериализации YAML — классическая «сериализация всего мира». " проблема, которая не заканчивается хорошо, когда у вас есть миллионы доступных объектов, как вы можете себе представить :)

Я нашел класс SnakeYaml 'Representer', который выглядит как хук, который позволяет вам указать «не» для сериализации определенного компонента, но похоже, что он не действует как прерыватель цепи в процессе навигации по графу объектов, когда он сталкивается с этим компонентом. Он не будет записывать вывод YAML для этого bean-компонента, но SnakeYaml, похоже, продолжает перемещаться по графу объектов за этим 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);
        }
    }
}

Есть ли способ заставить SnakeYaml не проходить мимо определенного компонента при сериализации графа объектов?


person Volksman    schedule 04.04.2018    source источник


Ответы (1)


Я только что смог ответить на свой вопрос :)

Что я делал неправильно, так это пытался остановить навигацию по графу объектов на уровне класса.

Что вам нужно сделать, чтобы разорвать навигацию, так это сделать это на уровне отдельного отношения/свойства, за пределы которого вы не хотите, чтобы SnakeYaml перемещался во время сериализации.

поэтому вместо

if (javaBean instanceof Role) {
    return null;

мне нужно было сделать

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

куда:

  • «ClassWithAttribute» — это имя класса с отношением, за пределами которого вы не хотите, чтобы сериализация продолжалась.
  • «classAttributeName» — это имя атрибута отношения, после которого вы не хотите, чтобы сериализация продолжалась.
person Volksman    schedule 04.04.2018