2011-03-17 34 views
8

Estoy tratando de serializar POJO a JSON, pero atascado en el problema de referencia circular. Sé cómo manejar uno a muchos y revertir relaciones usando @JsonBackReference y @JsonManagedReference.¿Cómo resolver referencias circulares en el serializador json causado por muchos TO Muchos hibernan mapeo bidireccional?

Mi problema es con la relación bidireccional de muchos a muchos (por ejemplo, un estudiante puede tener muchos cursos y cada curso puede tener muchos estudiantes inscritos), las referencias de los padres las referencias secundarias y secundarias y aquí mi serializador muere. Según mi entender, no puedo usar @JsonBackReference aquí ya que el tipo de valor de la propiedad debe ser un bean: no puede ser una colección, mapa, matriz o enumeración.

¿Puede alguien aconsejar cómo puedo manejar este escenario?

Respuesta

8

Puede usar @JsonIgnoreProperties("someField") en uno de los lados de las relaciones (la anotación es de nivel de clase). O @JsonIgnore

+0

Esto, más algunas adiciones que mencionaré a continuación, resolvió un problema similar muy bien para mí. – jpitt42

-1

si tiene el objeto de colección que así sea

collection<object> listobj 

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

Esto debería funcionar y el objeto se obtiene ahora puede ser JSON serializado y su limpia

+0

. La solución .NET/LINQ no funciona en Java/Spring – wrschneider

0

También puede utilizar dormilón de mapeo para convertir una POJO a un mapa y excluir campos. Por ejemplo si tenemos dos clases PojoA y PojoB tener relaciones bi-direccional, podemos definir el mapeo como esto

<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> 

A continuación, definir un ajuste del archivo de asignación de empuje por encima como una propiedad del bean.

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

Luego, en la clase que donde están serializar

public class TestClass 
{ 
    @Autowired 
    DozerBeanMapper mapper; 

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

Dozer manual here.

0

Dao y lo que ya se ha mencionado @Bozho ...

estoy atascado con Jackson 1 en este momento porque estoy usando Google Cloud Endpoints, así que esto todavía podría ayudar a algunas personas a pesar de que Jackson 2 ha estado fuera por un momento. Aunque no necesito deserializar todo el objeto, la referencia sigue siendo muy necesaria.

Puse @JsonIgnore en los campos que causan la referencia circular, pero luego creé un nuevo getter para cada uno de ellos, de modo que todavía se devuelve una referencia plana en mis API.

@JsonIgnore 
private FooClass foo; 

public String getFooKey() 
... 

Con Cloud Endpoints, esto resulta en una "fooKey" plana que se devuelven en la carga útil GET, omitiendo "foo".

1

Como @Bozho ha respondido para usar @JsonIgnoreProperties, intente esto, funcionó para mí.

continuación son mis modelos con @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>(); 
} 

En valor del atributo de @JsonIgnoreProperties, tenemos que proporcionar la propiedad tipo de colección de la lucha contra el modelo (relacionado).

Cuestiones relacionadas