2016-02-11 16 views
6

Ho trovato una gran quantità di risorse su questo, come questo - Infinite Recursion with Jackson JSON and Hibernate JPA issue. Ho provato per implementare tutti i vari suggerimenti descritti qui (incluso base @ JsonIgnore), ma senza risultato. Non riesco a ottenere altro che errori di ricorsione infiniti, indipendentemente da quello che cerco. Penso di avere un setup abbastanza simile/tipico, ma ovviamente con qualcosa di sbagliato poiché nonostante utilizzo le annotazioni @JsonManagedReference, @JsonBackReferencere e @JsonIdentityInfo, continuo a ricevere l'errore.Ricorsione infinita con Jackson JSON e Hibernate JPA problema (ancora un altro)

Le mie tabelle sono "exchange" e "stock", con un numero molto elevato tra loro, e sono stato testato da ExchangeEndpoint. Ho confermato che se rimuovo completamente "stock" dall'entità "exchange", il servizio funziona correttamente, ma per qualche motivo, le annotazioni JSON non sembrano avere alcun effetto. Di seguito è riportato ciò che I pensa che la soluzione sia basata sulla seconda (ma più popolare) risposta nel già citato Infinite Recursion with Jackson JSON and Hibernate JPA issue.

Exchange.java

@Entity 
@Table(name = "exchange", schema = "public") 
@XmlRootElement 
@JsonIdentityInfo(generator=ObjectIdGenerators.IntSequenceGenerator.class, property="@id") 
public class Exchange implements java.io.Serializable { 
... 
    @OneToMany(fetch = FetchType.LAZY, mappedBy = "exchange") 
    @JsonManagedReference 
    public Set<Stock> getStocks() { 
     return this.stocks; 
    } 
... 

Stock.java

@Entity 
@Table(name = "stock", schema = "public") 
@XmlRootElement 
@JsonIdentityInfo(generator=ObjectIdGenerators.IntSequenceGenerator.class, property="@id") 
public class Stock implements java.io.Serializable { 
... 
    @ManyToOne(fetch = FetchType.LAZY) 
    @JoinColumn(name = "exchangeid", nullable = false) 
    @JsonBackReference 
    @JsonIgnore 
    public Exchange getExchange() { 
     return this.exchange; 
    } 
... 

ExchangeEndpoint.java

@Stateless 
@Path("/exchanges") 
public class ExchangeEndpoint { 
    @PersistenceContext(unitName = "postgresql-ss4") 
    private EntityManager em; 
... 
    @GET 
    @Produces("application/json") 
    public List<Exchange> listAll(@QueryParam("start") Integer startPosition, 
      @QueryParam("max") Integer maxResult) { 
     TypedQuery<Exchange> findAllQuery = em 
       .createQuery(
         "SELECT DISTINCT e " 
         + "FROM Exchange e " 
         + "LEFT JOIN FETCH e.stocks " 
         + "ORDER BY e.exchangeid", 
         Exchange.class); 
     if (startPosition != null) { 
      findAllQuery.setFirstResult(startPosition); 
     } 
     if (maxResult != null) { 
      findAllQuery.setMaxResults(maxResult); 
     } 
     final List<Exchange> results = findAllQuery.getResultList(); 
     return results; 
    } 

edit:

alcuni dei output di errore per essere sicuro che' Non mi fraintendere g qualcosa;

15: 35: 16.406 ERRORE [org.jboss.resteasy.resteasy_jaxrs.i18n] (HTTP/0.0.0.0: 8080-1) RESTEASY000100: Impossibile eseguire GET /scambi /: org.jboss. resteasy.spi.WriterException: org.codehaus.jackson.map.JsonMappingException: Infinita ricorsione (StackOverflowError) (attraverso la catena di riferimenti: net.hb.forge2RestServices.model.Exchange ["stocks"] -> org.hibernate.collection .internal.PersistentSet [0] -> net.hb.forge2RestServices.model.Stock ["exchange"] -> net.hb.forge2RestServices.model.Exchange ["stocks"] -> org.hibe ... . .. Scambio ["scorte"] -> org.hibernate.collection.internal.P ersistentSet [0] -> net.hb.forge2RestServices.model.Stock ["exchange"] -> net.hb.forge2RestServices.model.Exchange ["stocks"]) all'indirizzo org.jboss.resteasy.core.ServerResponse.writeTo (ServerResponse.java:262)

Per favore fatemi sapere quali informazioni aggiuntive posso fornire per aiutare a spiegare la mia debacle. Tiy.

risposta

0

Il problema è che si ha riferimento a Stock s e ritorno da Stock si ha riferimento a Exchange. Pertanto, JSON va a magazzino, torna a Exchange e quindi per Exchange genererà a tutti Stock s e così via.

Per interrompere il ciclo è preferibile inserire l'annotazione JsonIgnore nel campo che fa riferimento all'oggetto padre - ManyToOne - in questo caso è il campo Stock.exchange (o il getter per quello).

+0

Ho provato ad aggiungere l'annotazione JsonIgnore in un paio di modi diversi, ma ancora non sembra niente si sta comportando in modo diverso. Ho aggiornato la domanda originale con uno di loro, dove l'ho appena attaccato, ma ho anche provato a sostituire JsonBackReference e spostare le annotazioni nella definizione del campo (invece del getter), ma mi sembra di ottenere gli stessi risultati. C'è un modo in cui queste annotazioni potrebbero essere negate? – swv

2

Questo tipo di problemi è molto più facilmente evitato se non si espongono le entità JPA tramite REST.

È consigliabile considerare l'utilizzo di DTO sul lato REST e mappare entità a DTO e viceversa codificando manualmente un mapper o generando uno utilizzando MapStruct.

Come bonus si eviteranno problemi di sicurezza.

+0

MapStruct sembra interessante. Speravo che questo progetto non sarebbe diventato abbastanza sofisticato da richiedere davvero l'aggiunta di un altro livello come questo, ma posso immaginare molti altri progetti che lo faranno. Grazie per il riferimento. – swv

1

Sembra che il problema fosse con le importazioni. Non sono sicuro del perché, ma lo org.codehaus.jackson.annotate.JsonIgnore funziona per me e lo com.fasterxml.jackson.annotation.JsonIgnore no.

1

Usa @JsonManagedReference, @JsonBackReference

public class User { 
    public int id; 
    public String name; 

    @JsonBackReference 
    public List<Item> userItems; 
} 


public class Item { 
    public int id; 
    public String itemName; 

    @JsonManagedReference 
    public User owner; 
} 

Nota che:

@JsonManagedReference è la parte anteriore del riferimento - quello che viene serializzato normalmente. @JsonBackReference è la parte posteriore di riferimento - verrà omessa dalla serializzazione.

http://www.baeldung.com/jackson-bidirectional-relationships-and-infinite-recursion

Problemi correlati