2017-08-16 2 views
6

検索中に見つけたいくつかのことを試しましたが、何も助けなかったし、正しく実装しなかった。サイクルにつながる直接自己参照スーパークラスの問題JSON

エラー私は、それは同様appInstanceを持っているこれらの両方のは、基本エンティティを拡張し、ベース(スーパークラス)に

Direct self-reference leading to cycle (through reference chain: io.test.entity.bone.Special["appInstance"]->io.test.entity.platform.ApplicationInstance["appInstance"]) 

を取得しています。

基本エンティティが AppInstance

含まれている特別で

@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, include = JsonTypeInfo.As.PROPERTY, property = "objectType") 
@JsonIgnoreProperties({"createdBy", "appInstance", "lastUpdatedBy"}) 
public class Special extends BaseEntity implements Serializable { 

    @NotNull 
    @Column(nullable = false) 
    private String name; 

    @Column(length = Short.MAX_VALUE) 
    private String description; 

    @NotNull 
    @Column(nullable = false) 
    private Double price; 

    @OneToOne 
    private Attachment image; 

    @Enumerated(EnumType.STRING) 
    @ElementCollection(targetClass = SpecialTag.class) 
    @CollectionTable(name = "special_tags") 
    @Column(name = "specialtag") 
    private List<SpecialTag> specialTags; 

    @Temporal(TemporalType.TIME) 
    private Date specialStartTime; 

    @Temporal(TemporalType.TIME) 
    private Date specialEndTime; 

    @Enumerated(EnumType.STRING) 
    @ElementCollection(targetClass = WeekDay.class) 
    @CollectionTable(name = "available_week_days") 
    @Column(name = "weekday") 
    private List<WeekDay> availableWeekDays; 

    @OneToMany(mappedBy = "special", cascade = CascadeType.REFRESH) 
    private List<SpecialStatus> statuses; 

    @OneToMany(mappedBy = "special", cascade = CascadeType.REFRESH) 
    private List<SpecialReview> specialReviews; 

    @Transient 
    private Integer viewed; 

    private Boolean launched; 

    @OneToMany(mappedBy = "special") 
    private List<CampaignSpecial> specialCampaigns; 


    @Override 
    @JsonIgnore 
    public ApplicationInstance getAppInstance() { 
    return super.getAppInstance(); 
    } 
} 

すべてのエンティティがBaseEntityから継承この

public class ApplicationInstance extends BaseEntity implements Serializable { 
    private List<User> users; 
// some other properties (would all have the same base and application instance . User entity will look similar to the Special.) 
} 

特別実体のように見えるこの

@MappedSuperclass 
public abstract class BaseEntity implements Comparable, Serializable { 

@ManyToOne 
protected ApplicationInstance appInstance; 

//getter & setter 

} 

アプリケーションエンティティに似ています

その後、私は、次の

  • 追加jsonIgnoreProperties
  • が@JsonIgnore
  • に注釈を付けることappInstanceの上書きを追加しました試みた特別なエンティティで特別

    @GET 
    @Path("{ref}") 
    @Produces(MediaType.APPLICATION_JSON) 
    @Consumes(value = MediaType.TEXT_PLAIN) 
    public Special findByGuestRef(@PathParam("ref") String pRefeference) { 
        // find the special and return it 
    return special; 
    } 
    

    を取得する方法を持っています@JsonIdentityInfo

abovのリンクこれらのソリューションの作品の電子

なし。私は何か間違っているのですか?

注:他のエンティティが異なるパッケージにあり、編集したくないため、特別な編集もできますか?

+0

'protected ApplicationInstance appInstance'をプライベートにして、それに対していくつかのゲッターとセッターを追加します(protectedまたはpublicのいずれか)。次に、' @JsonIgnore'アノテーションで 'ApplicationInstance'のゲッターをオーバーライドします。 – ConductedClever

+0

@aristotllもう少し詳細を追加しましたが、変更されるとは思いません。アプリケーションインスタンス –

+0

を参照してください。appInstanceをこのインスタンスからのみ除外するので、マップされたクラスに '@ JsonIgnore'を追加できないのはなぜですか? – Mark

答えて

2

通常、レスポンス内の属性を除外するのは、ゲッタに@JsonIgnoreアノテーションを追加するのと同じくらい簡単ですが、このアノテーションを親クラスに追加しない場合は、ゲッタをオーバーライドしてアノテーションを追加することができます:

public class Special extends BaseEntity implements Serializable { 
    ... 
    @JsonIgnore 
    public ApplicationInstance getAppInstance() { 
     return this.appInstance; 
    } 
    ... 
} 

:いくつかのフレームワークがあるので、あなたは正しい@JsonIgnore注釈を使用しているか、それが無視されることを確認して、インスタンスのthis answerを参照してください。

別のオプション、より多くの「マニュアル」は、単に特別なインスタンスのサブセットになり、応答のためのBeanを作成している:

@GET 
@Path("{ref}") 
@Produces(MediaType.APPLICATION_JSON) 
@Consumes(value = MediaType.TEXT_PLAIN) 
public SpecialDTO findByGuestRef(@PathParam("ref") String pRefeference) { 
    // find the special and return it 
return new SpecialDTO(special); 
} 


public class SpecialDTO { 

    //declare here only the attributes that you want in your response 

    public SpecialDTO(Special sp) { 
     this.attr=sp.attr; // populate the needed attributes 
    } 

} 
+0

ありがとう、マニュアルが動作し、それを使用することができます。私は特別なような多くのエンティティを持っているし、それぞれのためのDTOクラスを作成したくないので、スーパークラスを編集する別の方法を試みます。 –

+0

私はそれをテストしていないので、それが動作するかどうか教えてください、それは単なる理論的な解決です –

+0

私はそれを試してもまだ動作しません。今のところ、私は "マニュアルオプション"を提案し、現在は動作します。 –

0

私には、問題は特別なオブジェクトであると思われるとフィールドが初期化されています。 シリアル化が発生したときに循環参照が検出されたと思います。似 何か:上記のコードで

class A { 
    public A child; 
    public A parent; 
} 

A object = new A(); 
A root = new A(); 
root.child = object; 
object.parent = root; 

、あなたはこれらのオブジェクトのいずれかをseralizeしようとするたび、あなたは同じ問題に直面するだろう。 パブリックフィールドは推奨されません。

私はあなたの特別なオブジェクトとそれに設定されている参照を覗いてみることをお勧めします。

+1

全体の質問を読んでください、OPはそれを知っています。問題は、問題のある属性を宣言する親クラスを変更せずに修正する方法です –

関連する問題