【发布时间】:2018-01-09 01:44:12
【问题描述】:
我有一个 TreeNode 实体,它通过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 值永远不会设置。为什么nodes 的延迟加载不起作用?我试过它急切的加载,但没有工作。或者,我正在为每个查找和保存创建新事务,但它非常慢,并且选择查询随着树大小的增加而不断增加。
【问题讨论】:
标签: java spring hibernate jpa spring-data-jpa