2010-11-05 1 views
0

J'utilise OpenJPA 1.2.x (JPA1). Le problème est que je ne peux pas continuer à interroger la structure arborescente en utilisant JPQL.OpenJPA 1.2.x sélection de la structure arborescente en utilisant JPQL

S'il vous plaît, voir mon entité:

@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; 

Et ma méthode de haricot apatride:

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

Mon but est d'obtenir l'arbre complet du département à partir de la racine. J'ai essayé cette approche:

Est-ce vrai? J'utilise DB2. Et l'utilisera à l'avenir. JPA query for getting the whole tree

Cela semble ne fonctionne pas: http://www.tikalk.com/java/load-a-tree-with-jpa-and-hibernate

J'ai essayé de répéter, mais j'obtiens l'erreur stackoverflow en traversant l'arbre (ne pas avoir plus de 200 nœuds du tout). La sortie de débogage a montré que la racine a elle-même comme un enfant, donc c'est une structure ...

Que dois-je essayer par la suite?

UPD: Voici mon code traverse:

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 ("title # printNode de [{}] children.size() [{}]", dep.getLabel() , (dep.getChildren() == null? "NULL": dep.getChildren(). size()));

sorties toujours: "title #printNode [Tous les départements] children.size() [19]" On dirait que la racine ("Tous les départements") a 19 enfants. C'est vrai, je l'ai vérifié dans ma base de données. Mais chaque enfant est la racine! Donc c'est une structure infinie ... ??? La racine n'a pas d'enfants? Il se récupère?

+0

Pensez que vous voulez dire OpenJPA 1.2.x. C'est JPA1.0 – DataNucleus

+0

Je veux dire que 1.0 et 1.2 a de grandes différences. Par exemple, 1.0.x ne prenait pas en charge les fonctions d'agrégation ORDER BY (COUNT, e.t.c.) dans JPQL. Je pense que nous devons garder à l'esprit la version actuelle du fournisseur d'implémentation. – Sergey

Répondre

1

J'ai essayé de répéter, mais j'obtiens une erreur de stackoverflow lors de la traversée de l'arborescence (ne pas avoir plus de 200 nœuds). La sortie de débogage a montré que la racine a elle-même comme un enfant, donc c'est une structure ronde ...

Ensuite, vos données sont très probablement erronées. Vérifiez que la racine n'a pas de parent.

0

Je pense que ce que vous faites est correct et devrait fonctionner. Vous chargez la structure arborescente complète dans le contexte de persistance, puis obtenez une référence au nœud racine. Peut-être que quelque chose ne va pas avec votre arbre qui traverse? Ce serait la seule chose qui pourrait causer un StackOverflowError. Pourriez-vous poster votre code?

+0

Voici une aide simple qui accepte Department comme une racine de l'arbre et "imprime" la vue html pour l'arbre. Quand je surmonterai le problème avec l'arbre, je passerai à un moteur de template. – Sergey

0

S'il vous plaît voir mon DB struccture:..

ID PARENT_ID LABEL 
0  0  All Departments 
1000 0   Central office 

C'est pourquoi JPA ne fonctionne pas :(

Voir la première ligne Il est la racine de l'arbre Semble JPA lire comme enfant faisant référence à lui-même (PARENT_ID existe dans le tableau, alors joignez-vous peut être effectuée)

J'ai modifier les valeurs de DB:.

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

Maintenant ça marche! Ouais! :)

Questions connexes