2012-05-14 6 views
6

Ho un servizio Web con file di classe Java che sono stati generati con NetBeans in base allo schema di database che ho.SAXException2: viene rilevato un ciclo nel grafico dell'oggetto. Qual è il caso?

ottengo strane eccezioni a volte e uno di loro è questa:

javax.xml.ws.WebServiceException: javax.xml.bind.MarshalException 
- with linked exception: 
[com.sun.istack.internal.SAXException2: A cycle is detected in the object graph. This will cause infinitely deep XML: org.mylib.Person[ personId=1 ] ->org.mylib.TeamPerson[ teamPersonPK=org.mylib.teamPersonPK[ teamId=1, personId=1 ] ] -> org.mylib.Person[ personId=1 ]] 

Googled questa eccezione e trovato alcuni casi simillar, ma non riesco ancora a capire il problema. Ho appena generato queste classi (Person.java, Team.java, TeamPerson.java) con NetBeans, quindi come può verificarsi il problema?

Questo accade quando cerco di ottenere tutte le persone:

Iterator iter = team.getTeamPersonCollection().iterator(); 
while(iter.hasNext()) { 
      Person person = ((TeamPerson)iter.next()).getPerson(); 
... 
} 

EDIT
Se rimuovo il riferimento della squadra dal TeamPerson ricevo il seguente errore:

Internal Exception: Exception [EclipseLink-7154] (Eclipse Persistence Services - 2.2.0.v20110202-r8913): org.eclipse.persistence.exceptions.ValidationException 
Exception Description: The attribute [teamPersonCollection] in entity class [class org.mylib.Team] has a mappedBy value of [team] which does not exist in its owning entity class [org.mylib.TeamPerson]. If the owning entity class is a @MappedSuperclass, this is invalid, and your attribute should reference the correct subclass. 
    at org.eclipse.persistence.exceptions.PersistenceUnitLoadingException.exceptionSearchingForPersistenceResources(PersistenceUnitLoadingException.java:126) 

EDIT 2
Le parti delle classi generate hanno questo aspetto:

Team.java

public class Team implements Serializable { 
    private static final long serialVersionUID = 1L; 
    @Id 
    @Basic(optional = false) 
    @Column(name = "team_id") 
    private Integer teamId; 
    @Column(name = "type") 
    private String type; 
    @OneToMany(cascade = CascadeType.ALL, mappedBy = "team") 
    private Collection<TeamPerson> teamPersonCollection; 

Person.java

public class Person implements Serializable { 
    private static final long serialVersionUID = 1L; 
    @Id 
    @Basic(optional = false) 
    @Column(name = "person_id") 
    private Integer personId; 
    @Column(name = "name") 
    private String name; 
    @OneToMany(cascade = CascadeType.ALL, mappedBy = "person") 
    private Collection<TeamPerson> teamPersonCollection; 

TeamPerson.java

public class TeamPerson implements Serializable { 
    private static final long serialVersionUID = 1L; 
    @EmbeddedId 
    protected TeamPersonPK teamPersonPK; 
    @Basic(optional = false) 
    @Column(name = "timestamp") 
    @Temporal(TemporalType.TIMESTAMP) 
    private Date timestamp; 
    @JoinColumn(name = "team_id", referencedColumnName = "team_id", insertable = false, updatable = false) 
    @ManyToOne(optional = false) 
    private Team team; 
    @JoinColumn(name = "person_id", referencedColumnName = "person_id", insertable = false, updatable = false) 
    @ManyToOne(optional = false) 
    private Person person; 

TeamPersonPK.java

@Embeddable 
public class TeamPersonPK implements Serializable { 
    @Basic(optional = false) 
    @Column(name = "team_id") 
    private int teamId; 
    @Basic(optional = false) 
    @Column(name = "person_id") 
    private int personId; 
+0

Ciao @Rox, hai risolto questo problema alla fine? Ho avuto la stessa cosa! – LppEdd

risposta

0

Beh, forse questo è perché è la classe Person contiene il campo di tipo TeamPerson e la TeamPerson contiene il campo di tipo Person. E il marshaller è confuso dall'analisi di tale ciclo init?

UPD. Forse avete bisogno di cambiare questo

@OneToMany(cascade = CascadeType.ALL, mappedBy = "team") 
    private Collection<TeamPerson> teamPersonCollection; 

a:

@OneToMany(cascade = CascadeType.ALL, mappedBy = "teamId") 
    private Collection<TeamPerson> teamPersonCollection; 

perchè campo team non esiste in classe TeamPerson?

+0

Se si rimuove il riferimento a Team da TeamPerson, ottengo un'altra eccezione. Vedi la mia modifica sopra. Come posso risolverlo? – Rox

+0

ha aggiornato la risposta. –

+0

Non lo so, la classe è stata generata in questo modo, 'mappedBy =" team "'. Non chiedermi il motivo, ma se cambio in 'teamId' ottengo un ValidationException:' È stata rilevata una mappatura incompatibile tra [class org.mylib.Person] e [class org.mylib.TeamPerson] Ciò si verifica in genere quando la cardinalità di una mappatura non corrisponde alla cardinalità del suo backpointer. Qualche altro suggerimento? – Rox

10

La soluzione è semplicemente aggiungere l'annotazione: "@XmlTransient" (javax.xml.bind.annotation.XmlTransient) al getter della proprietà che causa il ciclo.

+1

L'oggetto è richiesto come parte del JSON restituito @XmlTransient esclude completamente l'elemento – Paullo

+0

l'utente desidera che i dati facciano parte del JSON –

Problemi correlati