2010-11-05 49 views
0

我使用的是OpenJPA 1.2.x(JPA1)。問題是我無法繼續使用JPQL查詢樹結構。OpenJPA 1.2.x使用JPQL選擇樹結構

請參閱我的實體:

@NamedQueries(
     { 
      @NamedQuery(
      name="Department.getFullTree", 
      query="SELECT dep FROM Department dep LEFT JOIN fetch dep.children" 
      ) 
     } 
     ) 
@Entity 
public class Department { 

    public static final Long ROOT_ID = 0L; 

    @Id 
    @GeneratedValue(strategy=GenerationType.SEQUENCE, generator="DEPARTMENT_SEQ") 
    @SequenceGenerator(name="DEPARTMENT_SEQ", sequenceName="DEPARTMENT_SEQ", allocationSize=1) 
    @Column(name="ID") 
    private Long id; 

    @Column(name="PARENT_ID") 
    private Long parentId; 

    @ManyToOne(targetEntity = Department.class, fetch = FetchType.EAGER) 
    @JoinColumn(name = "PARENT_ID") 
    private Department parent; 

    @Column(name="LABEL") 
    private String label; 

    @OneToMany(mappedBy = "parent", 
       targetEntity = Department.class, 
       fetch=FetchType.LAZY, 
       cascade = {CascadeType.PERSIST, CascadeType.ALL}) 
    private List<Department> children; 

而且我的無狀態bean方法:

public Department getFullTree(){ 
    em.createNamedQuery("Department.getFullTree").getResultList(); 
    Department root = em.find(Department.class, Department.ROOT_ID); 
    return root; 
} 

我的目標是讓全科樹從根開始。 我試過這種方法:

這是真的嗎?我正在使用DB2。並將在未來使用它。 JPA query for getting the whole tree

這似乎是不工作: http://www.tikalk.com/java/load-a-tree-with-jpa-and-hibernate

我試圖重複,但我得到計算器錯誤,而(在所有沒有超過200個節點)遍歷樹。 調試輸出顯示root有自己作爲孩子,所以它是一個圓形的結構...

接下來我該怎麼做?

UPD: 這是我的橫動的代碼:

public class TreeTagHelper { 

    private static final Logger LOG = LoggerFactory.getLogger(TreeTagHelper.class); 

    private Department root; 
    private JspWriter out; 

    public TreeTagHelper(Department root, JspWriter out){ 
     LOG.trace("#init"); 
     this.root = root; 
     this.out = out; 
    } 

    public void printTree() throws Exception{ 
     LOG.trace("#printTree -> start"); 
     out.println("<ul id=\"tree-root\"> ");  
     for(Department dep : root.getChildren()){ 
      printNode(dep, out); 
     }  
     closeUL(out); 
     LOG.trace("#printTree -> end"); 
    } 

    public static void printNode(Department dep, JspWriter out) throws Exception{ 
     LOG.trace("#printNode title[{}] children.size()[{}]",dep.getLabel(), (dep.getChildren() == null ? "NULL" : dep.getChildren().size())); 
     openLI(out); 
     out.print("<span id=\"tree_node_"+dep.getId()+"\" class=\"ekp-tree-node\" onclick=\"ekpCommon.tree.toggleBullet(this)\">"+dep.getLabel()+"</span>"); 
     if(dep.getChildren()!=null){ 
      openUL(out); 
      for(Department child : dep.getChildren()){ 
       printNode(child, out); 
      } 
      closeUL(out); 
     } 

     closeLI(out); 
    } 

    public static void openUL(JspWriter out) throws Exception{ 
     out.println("<ul>"); 
    } 

    public static void closeUL(JspWriter out) throws Exception{ 
     out.println("</ul>");  
    } 

    public static void openLI(JspWriter out) throws Exception{ 
     out.println("<li>"); 
    } 

    public static void closeLI(JspWriter out) throws Exception{ 
     out.println("</li>");  
    } 

LOG.trace( 「#printNode標題[{}] children.size()[{}]」,dep.getLabel() ,(dep.getChildren()== null?「NULL」:dep.getChildren()。size()));

總是輸出:「#printNode標題[所有部門] children.size()[19]」 好像根( 「所有部門」)具有19個孩子。這是真的,我在我的數據庫中檢查過它。 但每個孩子都是根! 所以它是無限的結構...?根不會生孩子?它取自己?

+0

認爲你的意思是OpenJPA 1.2.x.那就是JPA1.0 – DataNucleus 2010-11-06 07:59:56

+0

我想說1.0和1.2有很大的不同。例如1.0.x不支持JPQL中的ORDER BY聚合函數(COUNT,e.t.c.)。我認爲我們必須記住實施提供者的實際版本。 – Sergey 2010-11-06 12:40:41

回答

1

我試過重複,但我遍歷樹(根本沒有超過200個節點)時,我得到stackoverflow錯誤。調試輸出顯示根本身就是一個孩子,所以它是一個圓形鏈接結構...

那麼你的數據很可能是錯的。仔細檢查根沒有父母。

0

我想你在做什麼是正確的,應該工作。您正在將完整的樹結構加載到持久性上下文中,然後獲取對根節點的引用。你的樹遍歷可能有問題嗎?這將是唯一可能導致StackOverflowError。你能發佈你的代碼嗎?

+0

這裏是簡單的助手,它接受Department作爲樹的根,並「打印」樹的html視圖。當我用樹解決問題時,我會轉向一些模板引擎。 – Sergey 2010-11-06 12:42:01

0

請參閱我的DB struccture:。

ID PARENT_ID LABEL 
0  0  All Departments 
1000 0   Central office 

這就是爲什麼JPA沒有工作:(

見第一行這是樹的根好像JPA讀它作爲孩子引用到它本身(PARENT_ID確實存在的表,所以加入可以執行)

我已經改變DB值:

ID PARENT_ID LABEL 
0  -1   All Departments 
1000 0   Central office 

現在,它的工作原理!是啊! :)