Как решить циклические ссылки в json-сериализаторе, вызванные многопоточным отображением Many TO Many? - PullRequest
9 голосов
/ 18 марта 2011

Я пытаюсь сериализовать POJO в JSON, но застрял в проблеме циклической ссылки.Я знаю, как обращаться с одним ко многим и менять отношения с помощью @JsonBackReference и @JsonManagedReference.

Моя проблема связана с двунаправленным отношением «многие ко многим» (например, у студента может быть много курсов, и в каждом курсе может быть зарегистрировано много студентов), родительские ссылки дочерние и дочерние ссылки возвращаются к родителю, и здесь мой сериализатор умирает.Насколько я понимаю, я не могу использовать @JsonBackReference здесь, так как тип значения свойства должен быть бином: это не может быть коллекция, карта, массив или перечисление.

Может кто-нибудь посоветовать, как мне справитьсяэтот сценарий?

Ответы [ 5 ]

9 голосов
/ 18 марта 2011

Вы можете использовать @JsonIgnoreProperties("someField") на одной из сторон отношений (аннотация на уровне класса).Или @JsonIgnore

2 голосов
/ 20 января 2016

Поскольку @ Божо ответил на использование @JsonIgnoreProperties, попробуйте это, у меня это сработало.

Ниже представлены мои модели с @JsonIgnoreProperties:

@Entity
public class Employee implements Serializable{
    @ManyToMany(fetch=`enter code here`FetchType.LAZY)
    @JoinTable(name="edm_emp_dept_mappg", 
        joinColumns={@JoinColumn(name="emp_id", referencedColumnName="id")},
        inverseJoinColumns={@JoinColumn(name="dept_id", referencedColumnName="id")})
    @JsonIgnoreProperties(value="employee")
    Set<Department> department = new HashSet<Department>();
}


@Entity
public class Department implements Serializable {
    @ManyToMany(fetch=FetchType.LAZY, mappedBy="department")
    @JsonIgnoreProperties(value="department")
    Set<Employee> employee = new HashSet<Employee>();
}

В атрибуте value @JsonIgnoreProperties нам необходимо предоставить свойство типа коллекции модели counter (related).

0 голосов
/ 12 ноября 2013

Объясняя, о чем @Bozho уже упоминал ...

Я застрял с Jackson 1 прямо сейчас, потому что я использую конечные точки Google Cloud, так что это может все же помочь некоторым людям, даже если Jackson 2 отсутствовал некоторое время. Даже если мне не нужно десериализовать весь объект, ссылка все еще очень необходима.

Я поместил @JsonIgnore в поля, вызывающие циклическую ссылку, но затем создал новый метод получения для каждого из них, чтобы плоская ссылка все еще возвращалась в моих API.

@JsonIgnore
private FooClass foo;

public String getFooKey()
...

В облачных конечных точках это приводит к тому, что плоский символ "fooKey" возвращается в полезную нагрузку GET, при этом пропуская "foo".

0 голосов
/ 18 марта 2011

Вы также можете использовать Dozer mapping для преобразования POJO в карту и исключения полей. Например, если у нас есть два класса PojoA и PojoB, имеющие двунаправленные отношения, мы определяем отображение следующим образом:

<mapping map-id="mapA" map-null="false">
  <class-a>com.example.PojoA</class-a>
  <class-b>java.util.Map</class-b>
  <field>
    <a>fieldA</a>
    <b>this</b>
  </field>  
  <field map-id="mapB">
      <a>pojoB</a>
      <b>this</b>
      <b-hint>java.util.Map</b-hint>
  </field>
</mapping>

<mapping map-id="mapB" map-null="false">
  <class-a>com.example.PojoB</class-a>
  <class-b>java.util.Map</class-b>
  <field-exclude>
    <a>pojoA</a>
    <b>this</b>
  </field-exclude>
</mapping>

Затем вы определяете bean-компонент, устанавливающий вышеуказанный файл сопоставления бульдозера, как свойство.

<bean id="mapper" class="org.dozer.DozerBeanMapper">
   <property name="mappingFiles">
    <list>
       <value>dozerMapping.xml</value>
    </list>
   </property>
</bean>

Тогда в классе, где вы сериализуете

public class TestClass
{
     @Autowired
     DozerBeanMapper mapper;

     public Map<String,Object> serializeObject(PojoA pojoA)
     {
          return ((Map<String, Object>) mapper.map(pojoA, Map.class, "mapA"));
     }
}

Инструкция по эксплуатации бульдозера .

0 голосов
/ 18 марта 2011

если у вас есть объект коллекции, пусть он будет

collection<object> listobj 

var jsonObj = from c in listobj
                  select new
                 {
                   Prop1 = c.Prop1
                    ...
                 }

Это должно сработать, и объект, который вы получите сейчас, может быть json сериализован и его можно очистить

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...