Spring @ResponseBody Json Циклический справочник

Я пытаюсь использовать Spring 3.x @ResponseBody для генерации ответа json/xml, я использую JPA 2.0 ORM, когда есть много-много соотношений b/w таблиц, тогда json выдает LazyInitializationException

Если я даю "нетерпеливое получение", то это переходит в циклическую ссылку.


person Sandeep Manne    schedule 15.03.2012    source источник
comment
Возможно, это не тот ответ, который вы ищете, но я также столкнулся с этой проблемой, и мне пришлось решить ее, написав собственные ObjectMapper и JsonSerializer, которые касались отношений.   -  person bvulaj    schedule 16.03.2012
comment
может ли кто-нибудь дать решение моей проблемы, это все еще держит мое развитие   -  person Sandeep Manne    schedule 16.03.2012
comment
Я вижу два решения, которые были опубликованы. Вы тоже пробовали?   -  person bvulaj    schedule 21.03.2012
comment
пользовательскую оболочку, которую я не пробовал, это последний вариант, который я пытаюсь рассмотреть, да, я вызываю методы для инициализации дочернего элемента, например, user.getGroups(), где группы имеют много-много отношений, и у него снова есть userList, который я не могу инициализировать потому что это снова вызовет циклическую проблему.   -  person Sandeep Manne    schedule 21.03.2012
comment
Вам нужны все эти ссылки в теле ответа?   -  person bvulaj    schedule 21.03.2012
comment
Мне не нужно, но аннотация @ManytoMany создает это, мне просто нужен пользователь и список групп   -  person Sandeep Manne    schedule 21.03.2012


Ответы (3)


Недавно я столкнулся с похожей проблемой: Jackson - сериализация сущностей с двунаправленным отношения (избегая циклов)

Таким образом, решение состоит в том, чтобы перейти на Jackson 2.0 и добавить к классам следующую аннотацию:

@JsonIdentityInfo(generator = ObjectIdGenerators.IntSequenceGenerator.class, 
                  property = "@id")
public class SomeEntityClass ...

Тогда проблема в том, что Spring не работает с Jackson 2.0. Это было решено следующим образом:

<bean id="jacksonMessageConverter"
          class="own.implementation.of.MappingJacksonHttpMessageConverter"/>

<bean class="org.springframework.web.servlet.mvc
             .annotation.AnnotationMethodHandlerAdapter">
        <property name="messageConverters">
            <list>
                <ref bean="jacksonMessageConverter"/>
            </list>
        </property>
        <property name="requireSession" value="false"/>
    </bean>

И own.implementation.of.MappingJacksonHttpMessageConverter основано на этом:

http://www.jarvana.com/jaRVana/view/org/springframework/spring-web/3.0.0.RELEASE/spring-web-3.0.0.RELEASE-sources.jar!/org/springframework/http/converter/json/MappingJacksonHttpMessageConverter.java?format=ok

Но используйте ObjectMapper и другие классы Jackson из Jackson 2.0 вместо Jackson 1.*

person Eugene Retunsky    schedule 10.04.2012

Судя по вашим комментариям, просто создайте кастомный Serializer.

Ваш JsonSerializer. Вы можете иметь их для каждого типа объекта, который вы пытаетесь сериализовать.

public class MyObjectJsonSerializer extends JsonSerializer<MyObject> {

@Override
public Class<MyObject> handledType() {
    return MyObject.class;
}

@Override
public void serialize(MyObject myObject, JsonGenerator jgen, SerializerProvider provider) throws IOException, JsonProcessingException {
    jgen.writeStartObject();
    jgen.writeNumberField("id", myObject.getId());
    // whatever else you need
    jgen.writeEndObject();
}

}

Ваш ObjectMapper.

public class MyObjectMapper extends ObjectMapper {

public MyObjectMapper() {
    SimpleModule module = new SimpleModule("My Module", new Version(1, 0, 0, "SNAPSHOT"));
    module.addSerializer(new MyObjectJsonSerializer());

    this.registerModule(module);
}

}

А затем в вашем spring-config.xml.

<mvc:annotation-driven>
    <mvc:message-converters>
        <bean class="org.springframework.http.converter.json.MappingJacksonHttpMessageConverter">
            <property name="objectMapper" ref="myObjectMapper" />
        </bean>
    </mvc:message-converters>
</mvc:annotation-driven>

<bean id="myObjectMapper" class="com.manne.app.objectmapper.MyObjectMapper" />
person bvulaj    schedule 21.03.2012

Похоже, вы сериализуете объект, управляемый ORM, в JSON, но не инициализировали все дочерние ассоциации, ведущие к LazyInitializationException, поскольку ваш контроллер не имеет дескриптора соединения с БД. 2 варианта:

  1. Инициализировать все дочерние ассоциации объектов на уровне DAO.
  2. Преобразуйте объект, управляемый ORM, в TO и передайте его контроллеру для преобразования в JSON.
person atrain    schedule 18.03.2012
comment
В моем сценарии у меня есть пользователи и группы со многими отношениями, если я инициализирую дочерние объекты группы в пользователе, то снова эта группа имеет пользователей в качестве дочерних объектов, если я инициализирую, что она войдет в цикл - person Sandeep Manne; 21.03.2012