自我引用@OneToMany



我有以下类

@Entity
public class Comment extends Base {
@ManyToOne(cascade = CascadeType.ALL, fetch = FetchType.EAGER)
private Comment inReplyTo;
@OneToMany(mappedBy = "inReplyTo", cascade = CascadeType.ALL, fetch = FetchType.EAGER)
private Collection<Comment> replies;
public Comment() {
}
public Collection<Comment> getReplies() {
    return replies;
}
public void setReplies(Collection<Comment> comments) {
    this.replies = comments;
}
public Comment getInReplyTo() {
    return inReplyTo;
}
public void setInReplyTo(Comment inReplyTo) {
    this.inReplyTo = inReplyTo;
}
}

添加新注释并设置inReplyTo工作,并且注释被保存到DB中。但是inReplyTo注释的replies字段为空。

也做

c.setReplies(new ArrayList<Comment>());
c.getReplies().add(x);
repo.save(c);

导致这个错误

org.datanucleus.store.types.IncompatibleFieldTypeException: Incompatible type requested for field "Comment.replies" : was java.util.Collection but should be java.util.Collection

任何想法?

如果我正确理解你的问题,你有类似这样的代码:

Comment parent = //...
Comment reply = new Comment();
reply.setInReplyTo(parent);
reply = commentRepository.save(reply);
Collection<Comment> parentReplies = parent.getReplies();

你想知道为什么parentRepliesnull

这是意料之中的,因为JPA 2.0规范的§2.9实体关系说:

请注意,是应用程序承担了维护运行时关系一致性的责任——例如,当应用程序在运行时更新关系时,要确保双向关系的"一方"one_answers"多方"彼此一致。

DataNucleus不负责实例化一个包含新的reply注释的新集合,并将parent的replies属性设置为该集合。我已经检查了DataNucleus 4.1.0和Hibernate 4.3.10,并验证了两者都不会更新in-reply-to Comment的replies属性。

您的应用程序需要确保运行时关系是一致的。例如,您可以向Comment类添加一个addReply()方法:

    public void addReply(Comment reply) {
        if (this == reply) throw new IllegalArgumentException("`reply' cannot be `this' Comment object because a comment cannot be a reply to itself.");
        if (replies == null) replies = new ArrayList<>();
        replies.add(reply);
        reply.setInReplyTo(this);
    }

那么添加回复的代码应该是这样的:

Comment parent = //...
Comment reply = new Comment();
parent.addReply(reply);
reply = commentRepository.save(reply);
Collection<Comment> parentReplies = parent.getReplies();

同样,我没有重复这个错误:

<>之前incompatiblefieldtypeexception:请求字段的类型不兼容。回复":是java.util.Collection,但应该是java.util.Collection

你应该设置这两个部分的关系:

c.setReplies(new ArrayList<Comment>());
c.getReplies().add(x);
c.setInReplyTo(x);//this is the most imporant
repo.save(c);

如果这不起作用,这可能是Datanucleus的一个错误:尝试报告它并在这里放置一个链接。

我升级到DataNucleus 4.1.1,做了一个清理,它开始工作了

最新更新