Mittwoch, April 8, 2020

Ein Zyklus entdeckt wird, in dem Objektdiagramm. Dadurch wird unendlich tief XML

Habe ich zwei DTO Objekte sagen, A und B, die mit Getter und setter und sind verwendet, um Daten aus der Datenbank. Das problem ist, wenn ich rufe A, B aufgerufen wird und in B wieder Punkte selbst zu Einem und es entsteht ein Kreislauf.

Kann ich nicht ignorieren/ausblenden die Methode ist, die der Schaffung des Zyklus. Ich brauche die ganzen Daten von A und B.

Gibt es eine Möglichkeit, es zu erreichen ?

Bitte helfen

Dies ist mein code, der das problem verursacht. Dies ist die Anwendung DTO, die aufrufende Umgebung DTO

@OneToMany(mappedBy="application", fetch=FetchType.LAZY
        ,cascade=CascadeType.ALL
        )
public Set<EnvironmentDTO> getEnvironment() {
    return environment;
}

public void setEnvironment(Set<EnvironmentDTO> environment) {
    this.environment = environment;
}

– Und das ist Umwelt-DTO das ist das aufrufen der Anwendung DTO

@ManyToOne(targetEntity=ApplicationDTO.class )
@JoinColumn(name="fk_application_Id") 
public ApplicationDTO getApplication() {
    return application;
}

public void setApplication(ApplicationDTO application) {
    this.application = application;
}

Hier radeln wird immer erstellt

Dies ist meine Ruhe nennen, die geben das Ergebnis in das XML-format und ich denke, beim erstellen von XML-Zyklus wird immer erstellt

@GET
@Path("/get")
@Produces({MediaType.APPLICATION_XML})
public List<ApplicationDTO> getAllApplications(){
    List<ApplicationDTO> allApplication = applicationService.getAllApplication();
    return allApplication;
}

Dies ist die Anwendung DTO-Klasse

@Entity
@Table(name="application")
@org.hibernate.annotations.GenericGenerator(
name ="test-increment-strategy",strategy = "increment")

@XmlRootElement
public class ApplicationDTO implements Serializable {

@XmlAttribute
public Long appTypeId;

private static final long serialVersionUID = -8027722210927935073L;

private Long applicationId;

private String applicationName;

private ApplicationTypeDTO applicationType;

private String applicationDescription;

private Integer owner;

private Integer createdBy;

private Integer assignedTo;

private Date createTime;

private Date modifiedTime;

private Set<EnvironmentDTO> environment;

@Id
@GeneratedValue(generator = "test-increment-strategy")
@Column(name = "applicationId")
public Long getApplicationId() {
    return applicationId;
}

private void setApplicationId(Long applicationId) {
    this.applicationId = applicationId;
}

@Column(name = "applicationName")
public String getApplicationName() {
    return applicationName;
}

public void setApplicationName(String applicationName) {
    this.applicationName = applicationName;
}

@ManyToOne(targetEntity=ApplicationTypeDTO.class 
        ,fetch = FetchType.LAZY
        )
@JoinColumn(name="applicationType")

public ApplicationTypeDTO getApplicationType() {
    return applicationType;
}

public void setApplicationType(ApplicationTypeDTO applicationType) {
    this.applicationType = applicationType;
}

@Column(name = "description")
public String getApplicationDescription() {
    return applicationDescription;
}

public void setApplicationDescription(String applicationDescription) {
    this.applicationDescription = applicationDescription;
}

@Column(name = "owner")
public Integer getOwner() {
    return owner;
}

public void setOwner(Integer owner) {
    this.owner = owner;
}

@Column(name = "createdBy")
public Integer getCreatedBy() {
    return createdBy;
}

public void setCreatedBy(Integer createdBy) {
    this.createdBy = createdBy;
}

@Column(name = "assignedTo")
public Integer getAssignedTo() {
    return assignedTo;
}

public void setAssignedTo(Integer assignedTo) {
    this.assignedTo = assignedTo;
}

@Column(name = "createTime")
public Date getCreateTime() {
    return createTime;
}

public void setCreateTime(Date createTime) {
    this.createTime = createTime;
}

@Column(name = "modifiedTime")
public Date getModifiedTime() {
    return modifiedTime;
}

public void setModifiedTime(Date modifiedTime) {
    this.modifiedTime = modifiedTime;
}

@OneToMany(mappedBy="application", fetch=FetchType.LAZY
        ,cascade=CascadeType.ALL
        )
public Set<EnvironmentDTO> getEnvironment() {
    return environment;
}

public void setEnvironment(Set<EnvironmentDTO> environment) {
    this.environment = environment;
}

Dies ist die Umgebung DTO-Klasse

@Entity
@Table(name="environment")

@org.hibernate.annotations.GenericGenerator(
name = "test-increment-strategy",
strategy = "increment")
@XmlRootElement
public class EnvironmentDTO implements Serializable {

@XmlAttribute
public Long envTypeId;

@XmlAttribute
public Long appId;

private static final long serialVersionUID = -2756426996796369998L;

private Long environmentId;

private String environmentName;

private EnvironmentTypeDTO environmentType;

private Integer owner;

private Date createTime;

private Set<InstanceDTO> instances;

private ApplicationDTO application;

@Id
@GeneratedValue(generator = "test-increment-strategy")
@Column(name = "envId")
public Long getEnvironmentId() {
    return environmentId;
}

private void setEnvironmentId(Long environmentId) {
    this.environmentId = environmentId;
}

@Column(name = "envName")
public String getEnvironmentName() {
    return environmentName;
}

public void setEnvironmentName(String environmentName) {
    this.environmentName = environmentName;
}

@ManyToOne(targetEntity=EnvironmentTypeDTO.class)
@JoinColumn(name = "envType")
public EnvironmentTypeDTO getEnvironmentType() {
    return environmentType;
}

public void setEnvironmentType(EnvironmentTypeDTO environmentType) {
    this.environmentType = environmentType;
}

@Column(name = "owner")
public Integer getOwner() {
    return owner;
}

public void setOwner(Integer owner) {
    this.owner = owner;
}

@Temporal(TemporalType.DATE)
@Column(name = "createTime")
public Date getCreateTime() 
{
    return createTime;
}

public void setCreateTime(Date createTime) {
    this.createTime = createTime;
}

@OneToMany(mappedBy="environment", cascade=CascadeType.ALL, fetch = FetchType.EAGER)
public Set<InstanceDTO> getInstances() {
    return instances;
}

public void setInstances(Set<InstanceDTO> instances) {
    this.instances = instances;
}

@ManyToOne(targetEntity=ApplicationDTO.class )
@JoinColumn(name="fk_application_Id")
//@XmlTransient 
public ApplicationDTO getApplication() {
    return application;
}

public void setApplication(ApplicationDTO application) {
    this.application = application;
}
  • Dein Titel sagt „Dadurch wird unendlich tief XML“, aber deine Frage sagt nichts über XML. Sie erwähnen die Existenz von Zyklen, sagen aber nichts darüber, warum die Zyklen sind ein problem. Was bist du eigentlich machen willst mit diesen Objekten?
  • Ich bin mit restful-web-services, um Daten aus der Datenbank und zeigen Sie Sie im XML-format im frontend
  • Ist das eigentlich gelöst mit XmlInverseReference ?
  • Eine Antwort ist auch bei stackoverflow.com/a/3074027/1851289 Könnte ein Duplikat.
InformationsquelleAutor Prats | 2013-06-25

3 Kommentare

  1. 9

    Ihre Objekt-graph zyklisch ist. Es gibt nichts wirklich falsch mit diesem, und es ist eine Natürliche Folge der Verwendung von JPA.

    Dein problem ist nicht, dass Ihr Objekt graph ist zyklisch, aber, dass Sie die Kodierung in ein format, das nicht in den Griff Zyklen. Dies ist nicht ein Hibernate-Frage, es ist eine JAXB Frage.

    Mein Vorschlag wäre, zu stoppen JAXB versucht, Marschall der application Eigenschaft des EnvironmentDTO Klasse. Ohne diese Eigenschaft der zyklischen graph wird zu einem Baum. Sie können dies tun, indem Sie untersuchen, dass das Eigentum mit @XmlTransient.

    (Geständnis: ich habe gelernt, über diese Anmerkung durch das Lesen ein blog-Beitrag von Herrn Doughan, die ich gestoßen bin, nach der Lektüre seiner Antwort auf diese Frage!)

    • Ich habe meine DTO-Klassen, bitte haben Sie einen Blick
    • Ich habe versucht @XmlTransient, aber mit diesem verbirgt environmentDTO Inhalt und die bekomme ich nur applicationDTO XML. Aber, ich brauche beide applicationDTO und environmentDTO in einer XML –
    • Könnten Sie bitte einen Weg vorschlagen, wie kann ich erreichen, sowohl die DTO ‚ s in einer XML –
    • Ich schlug vor, Sie kommentieren die application Eigenschaft des EnvironmentDTO Klasse mit @XmlTransient. Dies sollte nicht darüber hinwegtäuschen, andere Eigenschaften EnvironmentDTO. Hast du genau das, was ich vermutete?
  2. 5

    Hinweis: ich bin der EclipseLink JAXB (MOXy) führen und ein Mitglied der JAXB (JSR-222) expert group.

    MOXy bietet die @XmlInverseReference Erweiterung um dieses use case. Unten ist ein Beispiel dafür, wie wendet man diese Zuordnung auf zwei Entitäten mit einer bidirektionalen Beziehung.

    Kunden

    import javax.persistence.*;
    
    @Entity
    public class Customer {
    
        @Id
        private long id;
    
        @OneToOne(mappedBy="customer", cascade={CascadeType.ALL})
        private Address address;
    
    }

    Adresse

    import javax.persistence.*;
    import org.eclipse.persistence.oxm.annotations.*;
    
    @Entity
    public class Address implements Serializable {
    
        @Id
        private long id;
    
        @OneToOne
        @JoinColumn(name="ID")
        @MapsId
        @XmlInverseReference(mappedBy="address")
        private Customer customer;
    
    }

    Weitere Informationen

    • Diese Lösung erhält ein besseres Ergebnis als meins (mit @XmlTransient). Sie schließt allerdings die Verwendung von nicht-standard-Annotationen, die nur mit MOXy. Können wir erwarten, dass diese Anmerkungen Absolvent in der JAXB-standard, und wenn ja, haben Sie eine Idee, Wann?
    • Ich bin ganz neu JAXB, ich bin nicht in der Lage zu verstehen, wie MOXY S mit JAXB. Ich habe durch deine links, aber ich bin mir immer noch nicht klar, wie es zu benutzen. Könnten Sie bitte erklären, wie es zu benutzen ?
    • MOXy ist ein standard JAXB-provider, können Sie es durch hinzufügen einer jaxb.properties – Datei im gleichen package wie Ihr domain-Modell (siehe: blog.bdoughan.com/2011/05/…). Hier ist ein link zu einem Beispiel, das helfen kann: github.com/bdoughan/blog20110322
    • Ich habe jaxb.properties-Datei, aber mein eclipse ist nicht in der Lage zu erkennen @XmlInverseReference element. Muss ich hinzufügen, dass einige Gläser für die Verwendung von MOXy oder fügen Sie etwas in mein web.xml ziehen Sie in der MOXy in meinem Projekt ??
    • Ich habe auch heruntergeladen EclipseLink 2.5.0 nightly, aber was tun, nach dem Download. Sie haben nicht angegeben, es überall, wie es zu benutzen ?
    • Könnten Sie bitte empfehlen Sie mir eine Möglichkeit dies umzusetzen ?
    • Ich könnte Ihnen helfen, aus der Verwendung von Stack-Overflow-chat. Würde, dass die Arbeit für Sie?
    • Sicher, könnten Sie mir sagen, zu welcher Zeit Sie frei sind ?
    • Es ist wahrscheinlich am einfachsten Kontaktieren Sie mich unter folgendem link: blog.bdoughan.com/p/contact_01.html. Ich bin in der eastern time zone, also bin ich nicht sicher, wie das überschneidet sich mit, wo Sie sind.

  3. 1

    Mein Rat ist, nicht die Offenlegung Ihrer JPA-entity-Klasse für die webservices. Sie können erstellen verschiedene POJO Klasse und konvertieren Sie Ihre JPA-Entität zu den POJO. Zum Beispiel:

    dies ist Ihre JPA-entity

    import javax.persistence.*;
    
    @Entity
    public class Customer {
    
        @Id
        private long id;
    
        @OneToOne(mappedBy="customer", cascade={CascadeType.ALL})
        private Address address;
    
    }

    sollten Sie verwenden Sie diese Klasse für Ihre webservices:

    public class CustomerModel{
        private long id;
        //you can call different WS to get the Address class, or combine to this model
    
        public void setFromJpa(Customer customer){
            this.id = customer.id;
        }
    }

Kostenlose Online-Tests