2013-06-02 12 views
6

Sto lavorando con RestEasy, Jboss 7 e EJB 3.1. Sto creando un servizio web RESTful che restituisce i dati in formato JSON.@JsonIgnore e @JsonBackReference sono ignorati

Il problema è che ho una relazione @ManyToOne su una delle mie entità che causa una ricorsione infinita durante la serializzazione. Ho provato ad usare le annotazioni di Jackson @JsonIgnore e @JsonBackReference per risolvere il problema, ma sembra che vengano ignorate totalmente e la ricorsione infinita si sta ancora verificando.

Questo è il mio User Class:

class User { 
    private String userId; 
    private Role role; 

    @Id 
    @Column(name = "\"UserId\"", unique = true, nullable = false, length = 30) 
    public String getUserId() { 
     return this.UserId; 
    } 

    public void setUserId(String UserId) { 
     this.UserId = UserId; 
    } 

    @ManyToOne(fetch = FetchType.EAGER) 
    @JoinColumn(name = "\"RoleId\"", nullable = false) 
    //I have tried @JsonIgnore without @JsonBackReference 
    @JsonIgnore 
    //I have tried @JsonBackReference without @JsonIgnore 
    //Also I have tried @JsonBackReference and @JsonIgnore together 
    @JsonBackReference("role-User") 
    public Role getRole() { 
     return this.role; 
    } 
} 

Questa è una parte della mia classe Ruolo:

@JsonManagedReference("role-User") 
@OneToMany(cascade = CascadeType.ALL, fetch = FetchType.EAGER, mappedBy = "role") 
public Set<User> getUsers() { 
    return this.users; 
} 

Ho letto da qualche parte che dovrei registrare Jackson con la mia domanda per essere in grado di utilizzare annotazione Jaxb regolare quindi ho creato una classe

@Provider 
@Produces(MediaType.APPLICATION_JSON) 
public class JacksonContextResolver implements ContextResolver<ObjectMapper> { 
    public JacksonContextResolver() { 
     ObjectMapper mapper = new ObjectMapper(); 
     AnnotationIntrospector introspector = new JaxbAnnotationIntrospector(); 

     mapper.getDeserializationConfig().setAnnotationIntrospector(
       introspector); 
     mapper.getSerializationConfig().setAnnotationIntrospector(introspector); 
    } 

    public ObjectMapper getContext(Class<?> objectType) { 
     return objectMapper; 
    } 
} 

Il problema di cui sopra è che JaxbAnnotationIntrospector() è deprecato.

prega:

  • Ha qualche idea del perché le annotazioni Jackson vengono ignorati?
  • Come posso utilizzare le normali annotazioni XML JAXB anziché quelle di Jackson?
  • Cosa posso utilizzare al posto di JaxbAnnotationIntrospector()?

Una risposta a qualsiasi di queste domande è apprezzata, grazie.

Aggiornamento:

Per ora ho escluso resteasy-jackson-provider utilizzando jboss-deployment-structure.xml e sto usando Jettison invece. Voglio ancora sapere come potrei usare Jackson!

risposta

2

Guarda, ho qualcosa di simile a te e sta lavorando bene per me ...

@JsonBackReference("promotion-travel") 
@ManyToOne(cascade = CascadeType.ALL) 
    @JoinTable(name="PROMOTION_TRAVEL_REL", 
     joinColumns = @JoinColumn(name="TRAVEL_ID"), 
     inverseJoinColumns = @JoinColumn(name="PROMOTION_ID") 
) 
public Promotion getPromotion(){... 

E questo è quello che ho sul Entity1

@JsonManagedReference("promotion-travel") 
@OneToMany(mappedBy="promotion") 
public List<Travel> getTravelList(){... 

non so se spostando l'annotazione alla parte superiore cambierà nulla, ma questa è l'unica cosa che posso vedere ...

Cheers,

0

Il problema qui sembra essere relativo all'utilizzo di Set<User> anziché List<User>. Ho avuto esattamente lo stesso problema e il passaggio da Set<User> a List<User> ha risolto questo problema, altrimenti ho sempre ricevuto l'errore Infinite recursion da Jackson. Non so se questo è veramente un bug in Jackson o devi fornire altre annotazioni ecc. Quando usi Set.

3

Ho avuto questo problema e ho ottenuto lo stesso codice per funzionare aggiornando la versione della libreria di Jackson nella mia build (pom.xml) dalla 1.8.x alla 1.9.13. Se stai usando Maven, modifica il tuo pom.xml per contenere:

<dependency> 
     <groupId>org.codehaus.jackson</groupId> 
     <artifactId>jackson-mapper-asl</artifactId> 
     <version>1.9.13</version> 
    </dependency> 

documentazione non aiuta, ma sembra che i riferimenti alla schiena per i set non erano supportati nelle versioni 1.8.x.

0

sto usando primavera 4.0.1, hibernate 4.3.5, 1.9.2 e Jackson STS IDE

ho avuto la stessa eccezione, ma risolto annotando il setter da @Transient idont so perché ma funziona bene

Questo è il mio classi di entità User.class

//i get that suggestion from some sites 
    @JsonIgnoreProperties({ "hibernateLazyInitializer", "handler" }) 
    @Entity 
    @Table(name = "user", catalog = "someSchema")  
    public class User implements java.io.Serializable { 

     private String name; 
     private String password; 
     private String username; 
     private Set<Telephone> telephones = new HashSet<Telephone>(0); 

     @OneToMany(fetch = FetchType.LAZY, mappedBy = "user") 
     public Set<Telephone> getTelephones() { 
      return this.telephones; 
     } 

     public void setTelephones(Set<Telephone> telephones) { 
      this.telephones = telephones; 
     } 
    } 

Telephone.class

@Entity 
@Table(name = "telephone", catalog = "someSchema") 
public class Telephone implements java.io.Serializable { 


    private User user; 
    private String telephone; 

    @ManyToOne(fetch = FetchType.LAZY) 

    @JoinColumn(name = "user_id", nullable = false) 
    public User getUser() { 
     return this.user; 
    } 


    @Transient 
    public void setUser(User user) { 
    this.user = user; 
    } 

} 

concernente la registrazione Jackson a mia domanda, ho usato XML di configurazione

<mvc:annotation-driven> 
     <mvc:message-converters> 
      <bean 
       class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter"> 
       <property name="objectMapper"> 
        <bean 
         class="web.jsonConverters.HibernateAwareObjectMapper" /> 
       </property> 
      </bean> 
     </mvc:message-converters> 
    </mvc:annotation-driven> 

e la classe mapper

public class HibernateAwareObjectMapper extends ObjectMapper { 

    public HibernateAwareObjectMapper() { 
     Hibernate4Module hm = new Hibernate4Module(); 
     registerModule(hm); 
    } 
} 
4

uso import com.fasterxml.jackson.annotation.JsonBackReference; invece di import org.codehaus.jackson.annotate.JsonBackReference;.

Era il problema per me.

+0

@GeeKh si prega di provare il suggerimento di cui sopra. – user104309

+0

Questo ha funzionato per me (dopo alcuni giorni di lotta). Era necessario dopo aver aggiornato la versione di Jackson. Grazie user104309! –

+0

Facile da ottenere - stava costruendo contro Jackson 1.9, ma l'ambiente di sviluppo è già stato aggiornato a Jackson 2+, che non sa nulla delle vecchie annotazioni. –

Problemi correlati