自引用@OneToMany
Self referencing @OneToMany
我有以下class
@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 有效,评论将保存到数据库中。但是 inReplyTo 评论的回复字段为空。
也在做
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
有什么想法吗?
您应该设置关系的两个部分:
c.setReplies(new ArrayList<Comment>());
c.getReplies().add(x);
c.setInReplyTo(x);//this is the most imporant
repo.save(c);
如果这不起作用,则可能是 Datanucleus 中的错误:尝试报告它并在此处的某处放置 link。
如果我没有正确理解你的问题,你的代码类似于:
Comment parent = //...
Comment reply = new Comment();
reply.setInReplyTo(parent);
reply = commentRepository.save(reply);
Collection<Comment> parentReplies = parent.getReplies();
并且您想知道为什么 parentReplies
是 null
。
这是意料之中的,因为 JPA 2.0 规范的 §2.9 实体关系说:
Note that it is the application that bears responsibility for maintaining the consistency of runtime relationships—for example, for insuring that the “one” and the “many” sides of a bidirectional relationship are consistent with one another when the application updates the relationship at runtime.
DataNucleus 不负责实例化包含新 reply
评论的新集合以及将 parent
的回复 属性 设置到该集合。我已经检查了 DataNucleus 4.1.0 和 Hibernate 4.3.10 并确认它们都不会更新评论中的回复 属性.
您的应用程序需要确保运行时关系是一致的。例如,您可以将 addReply() 方法添加到 Comment class:
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();
此外,我没有重现错误:
org.datanucleus.store.types.IncompatibleFieldTypeException: Incompatible type requested for field "Comment.replies" : was java.util.Collection but should be java.util.Collection
我升级到 DataNucleus 4.1.1,进行了清理并开始工作。
我有以下class
@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 有效,评论将保存到数据库中。但是 inReplyTo 评论的回复字段为空。
也在做
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
有什么想法吗?
您应该设置关系的两个部分:
c.setReplies(new ArrayList<Comment>());
c.getReplies().add(x);
c.setInReplyTo(x);//this is the most imporant
repo.save(c);
如果这不起作用,则可能是 Datanucleus 中的错误:尝试报告它并在此处的某处放置 link。
如果我没有正确理解你的问题,你的代码类似于:
Comment parent = //...
Comment reply = new Comment();
reply.setInReplyTo(parent);
reply = commentRepository.save(reply);
Collection<Comment> parentReplies = parent.getReplies();
并且您想知道为什么 parentReplies
是 null
。
这是意料之中的,因为 JPA 2.0 规范的 §2.9 实体关系说:
Note that it is the application that bears responsibility for maintaining the consistency of runtime relationships—for example, for insuring that the “one” and the “many” sides of a bidirectional relationship are consistent with one another when the application updates the relationship at runtime.
DataNucleus 不负责实例化包含新 reply
评论的新集合以及将 parent
的回复 属性 设置到该集合。我已经检查了 DataNucleus 4.1.0 和 Hibernate 4.3.10 并确认它们都不会更新评论中的回复 属性.
您的应用程序需要确保运行时关系是一致的。例如,您可以将 addReply() 方法添加到 Comment class:
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();
此外,我没有重现错误:
org.datanucleus.store.types.IncompatibleFieldTypeException: Incompatible type requested for field "Comment.replies" : was java.util.Collection but should be java.util.Collection
我升级到 DataNucleus 4.1.1,进行了清理并开始工作。