java - 在对象图中检测到循环。这将导致无限深的 XML

标签 java hibernate jaxb

我有两个 DTO 对象,比如 A 和 B,它们具有 getter 和 setter,用于从数据库中获取数据。问题是当我调用 A 时,B 被调用并且 B 再次将自身指向 A 并创建一个循环。

我不能忽略/隐藏创建循环的方法。我需要获取 A 和 B 的全部数据。

有什么办法可以实现吗?

请帮忙

这是导致问题的我的代码。这是调用环境 DTO 的应用程序 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;
}

这是调用应用程序 DTO 的环境 DTO

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

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

这里正在创建循环

这是我的休息电话,它将以 XML 格式给出结果,我认为在创建 XML 循环时正在创建

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

这是应用程序 DTO 类

@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;
}

这是环境 DTO 类

@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;
}

最佳答案

您的对象图是循环的。这本质上并没有错,这是使用 JPA 的自然结果。

您的问题不在于您的对象图是循环的,而是您以无法处理循环的格式对其进行编码。这不是 Hibernate 问题,而是 JAXB 问题。

我的建议是阻止 JAXB 尝试编码(marshal) EnvironmentDTO 类的 application 属性。没有这个属性,循环图就变成了一棵树。您可以通过使用 @XmlTransient 注释该属性来做到这一点.

(忏悔:我通过阅读 a blog post by Mr Doughan 了解到这个注释,这是我在阅读他对这个问题的回答后发现的!)

关于java - 在对象图中检测到循环。这将导致无限深的 XML,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17295370/

相关文章:

java - 为什么 jpa/hibernate 在保存从 "select-then-update"方法检索的实体时仍然执行 "findBy",似乎它已分离

jaxb - @XmlPath (".") 与@XmlAdapter 冲突

web-services - 在 jboss fuse 中使用 cxf 的 Web 服务端点

java - 使用 : in the query string 在 Java 中创建 URI

spring - Grails + hibernate + Controller sessionFactory空对象?

java - Hibernate orphanRemoval是否可以在唯一的约束下工作?

java - JAXB 对象未实现可序列化的后果是什么?

java - 在 Java 中实现 Mixin?

java - 检测目录中添加的新文件或修改的现有文件

java - 分支处的堆栈图帧不一致 - Java8 Maven 单元测试