2012-05-14 25 views
6

Tengo un servicio web con archivos de clase Java que se han generado con NetBeans basado en el esquema de base de datos que tengo.SAXException2: Se detecta un ciclo en el gráfico de objetos. ¿Cuál es el caso?

me sale extrañas excepciones veces y uno de ellos es éste:

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 esta excepción y encontrado algunos casos simillar pero todavía no puede entender el problema. Acabo de generar esas clases (Person.java, Team.java, TeamPerson.java) con NetBeans entonces, ¿cómo puede ocurrir el problema?

Esto sucede cuando trato de conseguir todas las personas:

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

EDITAR
Si quito la referencia del equipo de TeamPerson me sale el siguiente error:

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
Las partes de las clases generadas se ven así:

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

Hola @Rox, ¿resolviste este problema al final? ¡Tengo lo mismo! – LppEdd

Respuesta

0

Bueno, tal vez sea porque su clase Person contiene el campo de tipo TeamPerson y la TeamPerson contiene el campo de tipo Person. ¿Y el marshaller se confunde al analizar ese loop init?

UPD. Tal vez usted necesita para cambiar esta

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

a:

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

porque el campo team no existe en la clase TeamPerson?

+0

Si elimino la referencia al equipo de TeamPerson, recibo otra excepción. Ver mi edición arriba. ¿Cómo puedo resolver eso? – Rox

+0

actualizó la respuesta. –

+0

No lo sé, la clase se generó así, 'mappedBy =" team "'. No me preguntes por qué, pero si cambio a 'teamId' obtengo una ValidationException:' Se ha encontrado una correspondencia incompatible entre [clase org.mylib.Person] y [clase org.mylib.TeamPerson] Esto generalmente ocurre cuando el la cardinalidad de un mapeo no se corresponde con la cardinalidad de su retroproyector. ¿Alguna otra sugerencia? – Rox

10

La solución es simplemente agregar la anotación: "@XmlTransient" (javax.xml.bind.annotation.XmlTransient) en el captador de la propiedad que causa el ciclo.

+1

El objeto es requerido como parte del JSON devuelto. @XmlTransient lo excluye completamente. – Paullo

+0

el usuario desea que los datos sean parte del JSON. –

Cuestiones relacionadas