JPA でグラフを保持しようとしましたが、うまくいきません。ノードであるリーフがあり、複数の親を持つことができ、親は複数の子 (ノード) を持つことができます。
@Entity
@Table(name = "NODES")
@Inheritance(strategy = InheritanceType.JOINED)
@DiscriminatorColumn(name = "KIND", discriminatorType = DiscriminatorType.STRING, length = 1)
public abstract class Node implements Serializable {
@Column(unique = true, name = "NAME", nullable = false, length = 50)
private String name;
@ManyToMany(mappedBy = "children", fetch = FetchType.LAZY)
@JoinTable(name = "NODE_PARENTS", joinColumns = { @JoinColumn(name = "NODEID", referencedColumnName = "ID") }, inverseJoinColumns = { @JoinColumn(name = "PARENTID", referencedColumnName = "ID") })
private Set<Parent> parents;
public Node() {
this.parents = new HashSet<Parent>();
}
public String getName() {
return this.name;
}
public void setName(String name) {
this.name = name;
}
public void setParents(Collection<Parent> parentList) {
for(Parent parent : this.parents) {
removeParent(parent);
}
for (Parent parent : parentList) {
addParent(parent);
}
}
public void addParent(Parent parent) {
this.parents.add(parent);
if (!parent.getMembers().contains(this)) {
parent.getMembers().add(this);
}
}
public void removeParent(ACLGroup parent) {
this.parents.remove(parent);
if (parent.getMembers().contains(this)) {
parent.getMembers().remove(this);
}
}
public Set<ACLGroup> getParents() {
return Collections.unmodifiableSet(this.parents);
}
}
@Entity
@Table(name = "LEAFS")
@DiscriminatorValue("L")
public class Leaf extends Node {
// some fields to persist
}
@Entity
@Table(name = "INNER_NODES")
@DiscriminatorValue("P")
public class InnerNodes extends Node implements Parent {
// some fields to persist
@ManyToMany(fetch = FetchType.LAZY)
private Set<Node> children;
public InnerNodes() {
this.children = new HashSet<Node>();
}
public Set<Node> getChildren() {
return Collections.unmodifiableSet(this.children);
}
public void setChildren(Set<Node> childList) {
for (Node child : this.children) {
removeChild(child);
}
for (Node child : childList) {
addChild(child);
}
}
public void addChild(Node child) {
this.children.add(child);
if (!child.getParents().contains(this)) {
child.addParent(this);
}
}
public void removeChild(Node child) {
this.children.remove(child);
if (child.getParents().contains(this)) {
child.removeParent(this);
}
}
}
public interface Parent {
Set<Node> getChildren();
void setChildren(Set<Node> childList);
void addChild(Node child);
void removeChild(Node child);
}
問題は、親インターフェイスを永続化できないことですが、円を防ぐために必要です。すべての Leaf または InnerNode は複数の親を持つことができ、すべての親は複数の子を持つことができます。
それを実装するアイデアはありますか?どうもありがとう。
アンドレ