无法处理托管/后向引用' defaultReference':后台引用类型(java.util.List)与托管类型不兼容(ForumAnswerReplay)

时间:2017-06-23 05:42:17

标签: java spring hibernate spring-mvc

论坛回答节省时间面临问题。在我使用@JsonIgnore成功保存之前,但现在我删除了@JsonIgnore annonation.and添加了@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)

Forum.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;
}

3 个答案:

答案 0 :(得分:11)

我认为你错放了@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 {
}

答案 1 :(得分:3)

删除ForumAnswer类中的@JsonManagedReference。

ForumAnswer类:

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

答案 2 :(得分:1)

对@OneToMany使用@JsonBackReference,为@ManyToOne关系使用@JsonManagedReference,以便让Jackson更好地处理这种关系。