【问题标题】:Can not handle managed/back reference 'defaultReference': back reference type (java.util.List) not compatible with managed type (ForumAnswerReplay)无法处理托管/反向引用“defaultReference”:反向引用类型 (java.util.List) 与托管类型 (ForumAnswerReplay) 不兼容
【发布时间】:2017-11-26 14:03:58
【问题描述】:

论坛回答节省了面临问题的时间。在我使用@JsonIgnore 成功保存之前,但现在我删除了@JsonIgnore annonation。并添加了@JsonBackReference 和@JsonManagedReference。

堆栈跟踪

java.lang.IllegalArgumentException: Can not handle managed/back reference 'defaultReference': back reference type (java.util.List) not compatible with managed type (com.tta.abcd.model.ForumAnswerReplay)
at com.fasterxml.jackson.databind.deser.BeanDeserializerBase._resolveManagedReferenceProperty(BeanDeserializerBase.java:790)
at com.fasterxml.jackson.databind.deser.BeanDeserializerBase.resolve(BeanDeserializerBase.java:516)
at com.fasterxml.jackson.databind.deser.DeserializerCache._createAndCache2(DeserializerCache.java:296)
at com.fasterxml.jackson.databind.deser.DeserializerCache._createAndCacheValueDeserializer(DeserializerCache.java:244)
at com.fasterxml.jackson.databind.deser.DeserializerCache.findValueDeserializer(DeserializerCache.java:142)
at com.fasterxml.jackson.databind.DeserializationContext.findContextualValueDeserializer(DeserializationContext.java:443)
at com.fasterxml.jackson.databind.deser.std.CollectionDeserializer.createContextual(CollectionDeserializer.java:196)
at com.fasterxml.jackson.databind.deser.std.CollectionDeserializer.createContextual(CollectionDeserializer.java:26)
at com.fasterxml.jackson.databind.DeserializationContext.handleSecondaryContextualization(DeserializationContext.java:681)
at com.fasterxml.jackson.databind.DeserializationContext.findContextualValueDeserializer(DeserializationContext.java:445)
at com.fasterxml.jackson.databind.deser.std.StdDeserializer.findDeserializer(StdDeserializer.java:967)

论坛.java

    @Entity
    @Table(name="Forum")
    public class Forum {

    @Id
    @GeneratedValue(strategy=GenerationType.AUTO)
    @Column(name="forumId")
    private Long forumId;

    @Column(name="question")
    private String question;

    @Column(columnDefinition="varchar(1000)",name="discription")
    private String discription;

    @Column(name="postedDate")
    private Date postedDate;

    @Fetch(value = FetchMode.SELECT)
    @OneToMany(cascade = CascadeType.ALL)
    @JoinColumn(name = "forumId")
    @JsonIgnore
    private List<ForumAnswer> forumList;
    }

ForumAnswer.java

    @Entity
    @Table(name="ForumAnswer")
    public class ForumAnswer {

    @Id
    @GeneratedValue(strategy=GenerationType.AUTO)
    @Column(name="forumAnswerId")
    private Long forumAnswerId;

    @ManyToOne
        @JoinColumn(name = "forumId",insertable=true, updatable=true,nullable=true)
    private Forum forum;

    @Column(name="answer")
    private String answer;

    @Column(name="answerDate")
    private Date answerDate;

    @Fetch(value = FetchMode.SELECT)
    @OneToMany(cascade = CascadeType.ALL)
    @JoinColumn(name = "forumAnswerId")
    @JsonBackReference
    private List<ForumAnswerReplay> forumAnswerReplayList;

    @Transient
    private List<ForumAnswerReplay> faqReplayList;
}

ForumAnswerReplay.java

@Entity
@Table(name="ForumAnswerReplay")
public class ForumAnswerReplay {

    @Id
    @GeneratedValue(strategy=GenerationType.AUTO)
    @Column(name="replayId")
    private Long replayId;

    @Column(name="replayToAnswer")
    private String replayToAnswer;

    @Column(name="replayToAnswerDate")
    private Date replayToAnswerDate;


    @ManyToOne(fetch=FetchType.EAGER)
    @JoinColumn(name="forumAnswerId",insertable=true,updatable=true,nullable=true)
        @JsonManagedReference
    private ForumAnswer forumAnswer;

    @Transient
    private String message;
}

控制器代码:

public ForumAnswer saveForumAns(@RequestBody ForumAnswer forumAns, BindingResult bindingResult, HttpSession session,
        HttpServletRequest request, HttpServletResponse response) {
    ForumAnswer forumDetails = forumService.saveForumAns(forumAns, bindingResult, session);
    if (forumDetails != null) {
        forumDetails.setMessage("success");
    }
    else {
        forumDetails.setMessage("failed");
    }
    return forumDetails;
}

DAO:

public ForumAnswer saveForumAns(ForumAnswer forumAns, BindingResult bindingResult) {

    final Session session = getSession();
    try {
        session.beginTransaction();
        Query query = session.createQuery("UPDATE ForumAnswer set answer =:answer,"
                + "forumAnswerId =:forumAnswerId,farmerUuid =:farmerUuid, answerDate =:answerDate");
        query.setParameter("answer", forumAns.getAnswer());
        query.setParameter("forumAnswerId", forumAns.getForumAnswerId());
        query.setParameter("farmerUuid", forumAns.getFarmer());
        query.setParameter("answerDate", forumAns.getAnswerDate());
        session.merge(forumAns);
        session.getTransaction().commit();
    } catch (Exception e) {
        e.printStackTrace();
        System.out.println("error while saving forum details" + e);
    } finally {
        session.close();
    }

    return forumAns;
}

【问题讨论】:

    标签: java spring hibernate spring-mvc


    【解决方案1】:

    对@OneToMany 使用@JsonBackReference,对@ManyToOne 关系使用@JsonManagedReference,让Jackson 更好地处理关系。

    【讨论】:

    • @ManyToMany 怎么样?
    • 如果你只想避免递归,你可以使用@JsonIdentityInfo 作为父类。您可以查看baeldung.com/… 以获得进一步说明。谢谢!
    • 每个人都在“baeldung”链接到那个“教程”,但它并没有真正解释任何东西。
    • \@JsonBackReference 继续孩子,非集合 \@ManyToOne。 fasterxml.github.io/jackson-annotations/javadoc/2.11/com/… \@JsonManagedReference 继续父级,\@OneToMany 集合
    【解决方案2】:

    删除 ForumAnswer 类中的 @JsonManagedReference。

    论坛回答类:

    @Fetch(value = FetchMode.SELECT)
        @OneToMany(cascade = CascadeType.ALL,fetch=FetchType.EAGER)
        @JoinColumn(name = "forumAnswerId")
        private List<ForumAnswerReplay> forumAnswerReplayList;
    

    ForumAnswerReplay:

    @JsonBackReference
    public ForumAnswer getForumAnswer() {
        return forumAnswer;
    }
    

    【讨论】:

      【解决方案3】:

      我认为您放错了@JsonManagedReference 和@JsonBackReference。

      @JsonManagedReference :它的前向引用部分,因此它将应用于集合类型。

      @JsonBackReference:它的引用后面部分。

      所以你的代码必须是这样的

        @JsonManagedReference 
           private List<ForumAnswerReplay> forumAnswerReplayList;
      
       @JsonBackReference
          private ForumAnswer forumAnswer;
      

      你也可以使用@JsonIdentityInfo你必须申请

      @JsonIdentityInfo(generator = ObjectIdGenerators.PropertyGenerator.class, 
                        property  = "forumAnswerId", 
                        scope     = Long.class)
      public class ForumAnswer {
      }
      
      @JsonIdentityInfo(generator = ObjectIdGenerators.PropertyGenerator.class, 
                        property  = "replyId", 
                        scope     = Long.class)
      public class ForumAnswerReplay {
      }
      

      【讨论】:

      • 感谢您的重播。在属性级别而不是 @JsonManagedReference 我正在使用 @JsonIdentityInfo(generator = ObjectIdGenerators.PropertyGenerator.class, property = "forumAnswerId") 但没有工作。我面临同样的问题。
      • @umapati:你必须删除 @JsonManagedReference@JsonBackReference 并在两个类上添加 @JsonIdentityInfo
      • 我删除了两个注释并添加了@JsonIdentityInfo 类级别。现在数据已成功保存,但检索时间数据未到达 ui。
      • 您只发布了保存代码。更新您的问题并编写您尝试检索的代码。
      • 所以@JsonBackReference 只适用于@ManyToOne@JsonManagedReference 只适用于@OneToMany
      猜你喜欢
      • 2017-11-13
      • 2016-09-18
      • 2018-10-08
      • 2015-03-26
      • 1970-01-01
      • 2019-07-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多