我有一个TreeNode实体,指向自己function getData() {
var data = [
{
animalname: "Cheetah",
id: 1,
sci_name: "Acinonyx jubatus"
},
{
animalname: "Lion",
id: 2,
sci_name: "African Lion"
}
];
showInfo(data);
}
getData();
function showInfo(data) {
var chartdiv = document.querySelector(".test");
// console.log("data: ", data);
data.forEach( function(data) {
// card
var card = document.createElement('div');
card.classList.add("card");
//content
var content = document.createElement('div');
content.classList.add('content');
content.innerHTML = data.animalname;
// append
chartdiv.appendChild(card);
card.appendChild(content);
});
}
关系。我们还需要兄弟姐妹之间的上下关系进行导航。
OneToMany
我正在尝试从制表符分隔文件中加载完整的树结构,其中每行代表一个新节点。 例如,
@Entity
@Table(name = "node")
@SecondaryTables({
@SecondaryTable(name = "hierarchy",
pkJoinColumns = @PrimaryKeyJoinColumn(name = "node",
referencedColumnName = "id")) })
public class TreeNode {
@Id
@Column(unique = true)
private String id;
@Column
private String label;
@ManyToOne
@JoinColumn(name = "parent", table = "hierarchy")
private TreeNode parent;
@Column(table = "hierarchy", name = "previous")
private String previous;
@Column(name = "next", table = "hierarchy")
private String next;
@OneToMany(cascade = CascadeType.ALL, fetch = FetchType.EAGER)
@JoinTable(name = "hierarchy", joinColumns = {@JoinColumn(name = "parent",
referencedColumnName = "id")}, inverseJoinColumns = {@JoinColumn(name = "node",
referencedColumnName = "id")})
private Set<TreeNode> nodes = new HashSet<>();
@Column(name = "updated_dt")
private Timestamp updatedDate;
public TreeNode getLastChild() {
for (TreeNode node : nodes) {
if (node.getNext() == null) {
return node;
}
}
return null;
}
// getter, setters, equals, hashcode
}
以下是加载记录的代码。
T1
T1 T2
T1 T2 T3
T1 T2 T4
}
但问题是永远不会加载@Transactional
public void loadTree(Scanner lines) {
while (lines.hasNextLine()) {
final String line = lines.nextLine();
try (Scanner scanner = new Scanner(line)) {
Iterator<String> nodes = scanner.useDelimiter("\t");
addChildNodes(nodes);
}
}
}
private TreeNode addChildNodes(final Iterator<String> nodes) {
TreeNode parentNode = null;
while (nodes.hasNext()) {
String nodeTerm = nodes.next();
if (!StringUtils.hasText(nodeTerm)) {
continue;
}
String id = generateId(parentNode, nodeTerm);
TreeNode node = repo.findOne(id);
if (node == null) {
node = new TreeNode(id, nodeTerm);
node.setParent(parentNode);
TreeNode previous = null;
if (parentNode != null)
previous = parentNode.getLastChild();
if (previous != null) {
node.setPrevious(previous.getId());
previous.setNext(node.getId());
}
node = repo.saveAndFlush(node);
if (previous != null) {
previous = repo.save(previous);
}
}
parentNode = node;
}
return parentNode;
列表,因为nodes
始终返回空列表,并且永远不会设置getLastChild
和previous
值。为什么next
的延迟加载不起作用?我试着加载,但没有工作。或者,我为每个查找和保存创建新事务,但它非常慢,并且随着树大小的增加,选择查询继续增加。
答案 0 :(得分:0)
您只在一个地方拨打setParent
:
node.setParent(parentNode);
parentNode
反过来又只在一个地方设置:
TreeNode parentNode = null;
因此节点的父节点永远不会被设置为除null
之外的任何内容。
答案 1 :(得分:0)
TreeNode.nodes
中的实体未加载,因为无法加载。您尚未将关联的任何一方声明为反面,因此JPA将其视为两个单独的关联(并且您从未设置TreeNode.nodes
)。如果这是您的意图,那么您需要明确设置TreeNode.nodes
。否则,您希望mappedBy
与@OneToMany
一起使用,并且您不能同时使用@JoinColumn
和@JoinTable
。
您似乎正在与JPA(而不是与JPA)合作。我不确定TreeNode.previous
和TreeNode.next
应该如何工作,但是对于辅助表和联接表使用表是一个很好的想法。我甚至认为JPA的行为对于这种情况没有明确的定义。无论如何,为什么不让他们两个一对一,懒惰的联想呢?