Java 直接自引用导致循环异常

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/20218568/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-13 00:23:23  来源:igfitidea点击:

Direct self-reference leading to cycle exception

javaserializationelasticsearchHymansondeserialization

提问by Global Warrior

I have a class; something like the following:

我有一堂课;类似于以下内容:

public abstract class ElasticSearchValue<T> {

  private Long txId;
  private Long currentTxId;
  private T previous;

  public Long getTxId() {
    return txId;
  }

  public void setTxId(Long txId) {
    this.txId = txId;
  }

  public Long getCurrentTxId() {
    return currentTxId;
  }

  public void setCurrentTxId(Long currentTxId) {
    this.currentTxId = currentTxId;
  }

  public Object getPrevious() {
    return previous;
  }

  public void setPrevious(T previous) {
    this.previous = previous;
  }

}

And a class that extends the class above

和一个扩展上面类的类

public class DailyActivity extends ElasticSearchValue<DailyActivity> {

  Long agentId;
  Date date;
  Long success;

  public Long getAgentId() {
    return agentId;
  }

  public void setAgentId(Long agentId) {
    this.agentId = agentId;
  }

  public Date getDate() {
    return date;
  }

  public void setDate(Date date) {
    this.date = date;
  }

  public Long getSuccess() {
    return success;
  }

  public void setSuccess(Long success) {
    this.success = success;
  }

  @Override
  public String toString() {
    return agentId + "_" + date.toString();
  }

}

Now, I have an object of type DailyActivity, and when I try to convert it into a JSON string, I get the following exception:

现在,我有一个类型为 的对象DailyActivity,当我尝试将其转换为 JSON 字符串时,出现以下异常:

Caused by: com.fasterxml.Hymanson.databind.JsonMappingException: Direct self-reference leading to cycle (through reference chain: com.pr.analysis.DailyActivity["previous"])

引起:com.fasterxml.Hymanson.databind.JsonMappingException:直接自引用导致循环(通过引用链:com.pr.analysis.DailyActivity["previous"])

I have looked for solution on google but the solution which I get asks to put jsonIgnoreto previous value which is not what I intent to do. Has anyone faced the same issue? Thanks

我已经在 google 上寻找解决方案,但我得到的解决方案要求将其设置jsonIgnore为以前的值,这不是我打算做的。有没有人遇到过同样的问题?谢谢

EDITI know there is a cycle in the class and I am asking how to deserialize the class which has a self reference?

编辑我知道类中有一个循环,我在问如何反序列化具有自引用的类?

回答by Yiheng Wang

I guess somewhere in your code. The previous of some instance of DailyActivity point to itself.

我想在你的代码中的某个地方。DailyActivity 的某个实例的前一个指向自身。

回答by ericbn

The self-reference is here:

自我参考在这里:

public class DailyActivity extends ElasticSearchValue<DailyActivity> {

You're saying DailyActivityis an ElasticSearchValue<DailyActivity>, which is by itself an ElasticSearchValue<ElasticSearchValue<DailyActivity>>, and this goes on infinitely...

你说的DailyActivity是 an ElasticSearchValue<DailyActivity>,它本身就是一个ElasticSearchValue<ElasticSearchValue<DailyActivity>>,而且这种情况是无限持续的......

Update:I would break that in two classes. Create DailyActivitywithout subclassing ElasticSearchValue:

更新:我会把它分成两节课。创建DailyActivity没有子类化ElasticSearchValue

public class DailyActivity {
  // the same content as your class above

then create another class like:

然后创建另一个类,如:

public class ElacticDailyActivity extends ElasticSearchValue<DailyActivity> {

回答by borjab

In this case you need to annotate the relationships with @JsonManagedReferenceand @JsonBackReferencelike this:

在这种情况下,您需要像这样使用@JsonManagedReference@JsonBackReference注释关系:

 @ManyToOne
 @JoinColumn(name = "company_id", referencedColumnName = "id")
 @JsonBackReference
 private Company company 

And

 @OneToMany(mappedBy="company")
 @JsonManagedReference
 private Set<Employee> employee = new HashSet<Employee>();

There is a nice example here

有一个很好的例子在这里

回答by MFIhsan

Try @JsonIdentityInfoannotation as given in this example. More details here http://wiki.fasterxml.com/HymansonFeatureObjectIdentity

尝试@JsonIdentityInfo本示例中给出的注释。更多细节在这里http://wiki.fasterxml.com/HymansonFeatureObjectIdentity

@JsonIdentityInfo(generator=ObjectIdGenerators.IntSequenceGenerator.class, property="@id")
public class Identifiable
{
    public int value;

    public Identifiable next;
}

回答by ValerioMC

SerializationFeaturehas a property called FAIL_ON_SELF_REFERENCESdefault is truebut you can set to falseto skip this kind of exception.

SerializationFeature有一个名为FAIL_ON_SELF_REFERENCESdefault is的属性,true但您可以设置false为跳过这种异常。

    ObjectMapper objectMapper = new ObjectMapper();
    objectMapper.configure(SerializationFeature.FAIL_ON_SELF_REFERENCES, false);

If you are using SpringBoot you can simply add spring.Hymanson.serialization.fail-on-self-references=false in your application.properties

如果你正在使用SpringBoot你可以简单地添加spring.Hymanson.serialization.fail-on-self-references=false 在你的application.properties