title: JPA / JPQL: find root elements of a unidirectional tree
body: <p>JPA / JPQL: find root elements of a unidirectional tree.</p>
  
  <p>I need some help to write a named query for the following problem.</p>
  
  <p>I have the following (simplified) definition of an entity (TNode) and can save/read it via JPA.
  The entity is unidirectional, so childs don't know the parent!</p>
  
  <p>Now I try to write a named query to get all root elements. </p>
  
  <p>I use JPA 2.0 (Hibernate) and found some hints in the internet, that unidirectional links are supported.</p>
  
  <p>A simple JUnit (4) is also attached, to create two trees and save it into the db. I removed all the asserts.</p>
  
  <p>If I run the Junit, the table looks as expected:</p>
  
  <pre><code>ID  NAME    CHILDS_ID
  1   A1  (null)
  2   A11 1
  3   B1  (null)
  4   B11 3
  </code></pre>
  
  <p>I added @JoinColumn to have the self reference in the same table. And the with simple SQL the problem 
  would be easy (WHERE childs_id = null). But how must I write this in JPQL?</p>
  
  <p>Thanks for the answers.</p>
  
  <p>Uwe</p>
  
  <pre><code>@Entity
  @Table(name = "TNode")
  @NamedQueries({ @NamedQuery(name = "getRootNodes", query = "FROM TNode tnode ......."), })
  public class TNode implements JPAObject {
      @Id
      @GeneratedValue
      private Integer id;
  
      private String name;
  
      @OneToMany(cascade = { CascadeType.REFRESH, CascadeType.MERGE, CascadeType.REMOVE })
      @JoinColumn
      private Set&lt;TNode&gt; childs = new HashSet&lt;TNode&gt;();
  
      // JPA only
      private TNode() {
      }
  
      public TNode(String name) {
      this.name = name;
      }
  
      public void add(TNode tNode) {
      childs.add(tNode);
      }
  
      @Override
      public Integer getId() {
      return id;
      }
  
      @Override
      public String getName() {
      return name;
      }
  }
  </code></pre>
  
  <p>Here the simplified Junit</p>
  
  <pre><code>@RunWith(Arquillian.class)
  public class TNodeTest {
      @Deployment
      public static Archive&lt;?&gt; createTestArchive() {
      //@formatter:off
      Archive&lt;?&gt; archive = ShrinkWrap.create(WebArchive.class, "test.war")
          .addPackages(true, DummyInterfaceForTest.class.getPackage())
          .addAsLibraries(FindMavenArtifact.find("com.thoughtworks.xstream:xstream:1.4.2"))
          .addAsLibraries(FindMavenArtifact.find("xmlpull:xmlpull:1.1.3.1"))
          .addAsResource("META-INF/persistence.xml", "META-INF/persistence.xml")
          .addAsResource("import.sql", "import.sql")
          .addAsWebInfResource(EmptyAsset.INSTANCE, "beans.xml");
      //@formatter:on
      System.out.println(archive.toString(true));
      return archive;
      }
  
      @Inject
      @DAO.DAOType(type = DAO.MODE.STATELESS)
      private DAO&lt;JPAObject&gt; dao;
  
      @Test
      public void testMutipleRoots() throws Exception {
      TNode root;
  
      root = new TNode("A1");
      root.add(new TNode("A11"));
  
      dao.saveOrUpdate(root);
  
      root = new TNode("B1");
      root.add(new TNode("B11"));
  
      dao.saveOrUpdate(root);
      }
  }
  </code></pre>