在同一事务中加载子节点

时间:2018-01-07 18:17:46

标签: java spring hibernate jpa spring-data-jpa

我有一个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始终返回空列表,并且永远不会设置getLastChildprevious值。为什么next的延迟加载不起作用?我试着加载,但没有工作。或者,我为每个查找和保存创建新事务,但它非常慢,并且随着树大小的增加,选择查询继续增加。

2 个答案:

答案 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.previousTreeNode.next应该如何工作,但是对于辅助表和联接表使用表是一个很好的想法。我甚至认为JPA的行为对于这种情况没有明确的定义。无论如何,为什么不让他们两个一对一,懒惰的联想呢?