2012-04-05 25 views
12

Utilizo la biblioteca Gson para convertir objetos Java a una respuesta Json ... el problema es que después de una solicitud JPA el objeto recuperado de DB no se puede convertir debido a una relación recursiva con otras entidades (see my previous question) por ejemplo:¿La forma más fácil de eliminar las relaciones recursivas bidireccionales?

public class Gps implements Serializable { 
    private static final long serialVersionUID = 1L; 
    @Id 
    @Basic(optional = false) 
    @Column(name = "IMEI", nullable = false, length = 20) 
    private String imei; 
    //some code here... 
    @OneToMany(cascade = CascadeType.ALL, mappedBy = "gpsImei", fetch = FetchType.LAZY) 
    private List<Coordonnees> coordonneesList; 


public class Coordonnees implements Serializable { 
    private static final long serialVersionUID = 1L; 
    @Id 
    @GeneratedValue(strategy = GenerationType.IDENTITY) 
    @Basic(optional = false) 
    @Column(name = "IDCOORDONNEES", nullable = false) 
    private Integer idcoordonnees; 
    //some code here... 
    @JoinColumn(name = "GPS_IMEI", referencedColumnName = "IMEI", nullable = false) 
    @ManyToOne(optional = false, fetch = FetchType.LAZY) 
    private Gps gpsImei; 

Mi código fuente:

EntityManagerFactory emf=Persistence.createEntityManagerFactory("JavaApplication21PU"); 
    GpsJpaController gjc=new GpsJpaController(emf); 

    Gps gps=gjc.findGps("123456789"); 

    for(int i=0;i<gps.getCoordonneesList().size();i++){ 
    gps.getCoordonneesList().get(i).setGpsImei(null); 
    } 

    Gson gson=new Gson(); 
    String json=gson.toJson(gps);//convert to json response 

    System.out.println(json); 

Como se puede ver aquí hice:

for(int i=0;i<gps.getCoordonneesList().size();i++){ 
    gps.getCoordonneesList().get(i).setGpsImei(null); 
    } 

solo para matar la relación recursiva estableciendo nulo para cada objeto GPS en la lista coordonneesList ..

En su opinión, esta es una buena solución o hay otro método más práctico? Gracias

Respuesta

25

Hay una extensión llamada Gson GraphAdapterBuilder que puede serializar objetos que contienen referencias circulares. He aquí un ejemplo muy simplificado del caso de prueba correspondiente:

Roshambo rock = new Roshambo("ROCK"); 
Roshambo scissors = new Roshambo("SCISSORS"); 
Roshambo paper = new Roshambo("PAPER"); 
rock.beats = scissors; 
scissors.beats = paper; 
paper.beats = rock; 

GsonBuilder gsonBuilder = new GsonBuilder(); 
new GraphAdapterBuilder() 
    .addType(Roshambo.class) 
    .registerOn(gsonBuilder); 
Gson gson = gsonBuilder.create(); 
System.out.println(gson.toJson(rock)); 

Esta impresora:

{ 
    '0x1': {'name': 'ROCK', 'beats': '0x2'}, 
    '0x2': {'name': 'SCISSORS', 'beats': '0x3'}, 
    '0x3': {'name': 'PAPER', 'beats': '0x1'} 
} 

Tenga en cuenta que la clase GraphAdapterBuilder es no incluido en gson.jar. Si desea usarlo, deberá copiarlo manualmente en su proyecto.

+1

Gracias! Esto fue un salvavidas cuando se trabaja con Hibernate. Me salvó un montón de problemas al convertir una entidad hibernate usando gson. – Knubo

+0

funciona en Android también. –

+3

¿qué jar contiene esta clase "GraphAdapterBuilder"? – pavan

2

No sé acerca de Gson pero estoy trabajando con Jackson. Busque un ejemplo de uso de su clase ObjectMapper. En cuanto a la recursión, use @JsonManagedReference y @JsonBackReference para detener eso. Mire esos, por ejemplo, el uso también.

1

Puede utilizar @Expose (serializar = false) para evitar el cobro al ser serializado.

0

Uso transitoria por ignorar @OneToMany Conjuntos para google.gson

Cuestiones relacionadas