简体   繁体   中英

JAXB. Advise correct annotations

There is a structure. I want to link the three entities in this way: the Company should contain id, name of company and the list of Departments, each Department has a list of Workers, id and name of department. Each worker has name, id.

+Company
-int companyId
-String companyName
-Set<Department> listOfDepartments = new HashSet<Department>();

+Department
-int departmentId
-String departmentName
-Set<Worker> listOfWorkers = new HashSet<Worker>();

+Worker
-int workerId
-String workerName

@XmlRootElement(name="Company")
@XmlAccessorType(XmlAccessType.FIELD)
@Entity
public class Company {
    @XmlAttribute(name = "id")
    @Id @GeneratedValue(strategy = GenerationType.AUTO)
    private int companyId;
    @XmlElement(name = "companyName")
    private String companyName;

    @XmlElement(name="Department")
    @OneToMany(mappedBy = "company", cascade=CascadeType.PERSIST, fetch = FetchType.EAGER)
    private Set<Department> listOfDepartments = new HashSet<Department>();


@XmlRootElement(name="Department")
@XmlAccessorType(XmlAccessType.FIELD)
@Entity
public class Department {
    @XmlAttribute(name = "id")
    @Id @GeneratedValue(strategy = GenerationType.AUTO)
    private int idDepartment;

    @XmlElement(name = "departmentName")
    private String departmentName;

    @ManyToOne()
    @JoinColumn(name="companyId")
    private Company company;

    @XmlElement(name="Worker")
    @OneToMany(mappedBy = "department", cascade = CascadeType.PERSIST, fetch = FetchType.EAGER)
    private Set<Worker> listOfWorkers = new HashSet<Worker>();


@XmlRootElement(name="Worker")
@Entity
public class Worker {
    @Id @GeneratedValue(strategy = GenerationType.AUTO)
    private int idWorker;

    private String workerName;

    @ManyToOne
    @JoinColumn(name="departmentId")
    private Department department;

ERROR:

A cycle is detected in the object graph. This will cause infinitely deep XML: ru.eldarkaa.dto.Company@d1e43ed -> 
ru.eldarkaa.dto.Department@6e55f58 -> ru.eldarkaa.dto.Company@d1e43ed]

How to avoid this cycle?

You have a bidirectional relationship in your model. To solve it you could do the following:

Solutions Using Standard JAXB Metadata

1 - @XmlTransient

You can map one direction of the relationship with @XmlTransient . This will cause the field/property not to marshal preventing the infinite loop. This field/property also won't unmarshal meaning that you will need to populate it yourself.

2 - @XmlID / @XmlIDREF

@XmlIDREF is how you map shared references with JAXB you can use this to map the back-pointer relationship.

Solutions Leveraging EclipseLink JAXB (MOXy) Extensions

Note: I'm the EclipseLink JAXB (MOXy) lead and a member of the JAXB (JSR-222) expert group.

You can use MOXy's @XmlInverseReference extension for this use case. It acts like @XmlTransient on the marshal operation, but will still populate the value on the unmarshal.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM