11

A と B という 2 つの DTO オブジェクトがあり、これらにはゲッターとセッターがあり、データベースからデータを取得するために使用されます。問題は、私が 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;
}
4

3 に答える 3

11

オブジェクト グラフは循環的です。それには本質的な問題はなく、JPA を使用することの当然の結果です。

あなたの問題は、オブジェクトグラフが循環的であることではなく、循環を処理できない形式でエンコードしていることです。これは Hibernate に関する質問ではなく、JAXB に関する質問です。

私の提案は、JAXB がクラスのapplicationプロパティをマーシャリングしようとするのを止めることです。EnvironmentDTOそのプロパティがなければ、巡回グラフはツリーになります。これを行うには、そのプロパティに で注釈を付けます@XmlTransient

(自白: この注釈については、この質問に対する彼の回答を読んだ後に出会ったDoughan 氏のブログ投稿を読んで知りました!)

于 2013-06-25T12:12:33.567 に答える
5

注: 私はEclipseLink JAXB (MOXy)のリーダーであり、JAXB (JSR-222)エキスパート グループのメンバーです。

MOXy は、@XmlInverseReferenceこのユース ケースを処理するための拡張機能を提供します。以下は、双方向の関係を持つ 2 つのエンティティにこのマッピングを適用する方法の例です。

お客様

import javax.persistence.*;

@Entity
public class Customer {

    @Id
    private long id;

    @OneToOne(mappedBy="customer", cascade={CascadeType.ALL})
    private Address address;

}

住所

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;

}

詳細については

于 2013-06-25T13:11:35.853 に答える