title: Hibernate Mapping Parent/Child Relationship
body: <p>I have a database table which contains a simple self parent/child relationship (categories) like this:</p>
  
  <pre><code>+------------+----------+--------------------+
  | categoryid | parentid | category_name      |
  +------------+----------+--------------------+
  |          1 |        0 | Java               |
  |          2 |        0 | SKM                |
  |          3 |        0 | Neuigkeiten        |
  |          4 |        0 | Neue Versionen     |
  |          5 |        0 | PlugIn             |
  ..
  |          9 |        2 | Subversion         |
  |         10 |        2 | DVCS               |
  |         11 |        2 | SVK                |
  |         12 |        2 | Bazaar             |
  |         13 |        2 | CVS                |
  |         14 |        2 | SpectrumSCM        |
  |         15 |        2 | Plastic SCM        |
  |         16 |        2 | Monotone           |
  |         17 |        2 | Mercurial          |
  |         18 |        2 | ClearCase          |
  </code></pre>
  
  <p>Now I've created a Hibernate mapping class CategoryBO with the above Table like this (AbstractBaseBO contains only two public methods getId() and setId()..):</p>
  
  <pre><code>@Entity
  @Table(name = TabellenNamen.CATEGORY)
  public class CategoryBO extends AbstractBaseBO {
  
      @Id
      @GeneratedValue(strategy = GenerationType.AUTO)
      @Column(name = "categoryid", nullable = false, unique = true)
      private Long Id;
  
      @Column(name = "category_name")
      private String categoryName;
  
      @ManyToOne( cascade = { CascadeType.ALL } )
      @JoinColumn(name = "parentid")
      private CategoryBO parent;
  
      @OneToMany(mappedBy = "parent")
      private ArrayList&lt;CategoryBO&gt; subCategories = new ArrayList&lt;CetegoryBO&gt;();
  
  
      ...getter/setters
  </code></pre>
  
  <p>}</p>
  
  <p>But if I try to get the list of category entries from the database i get the following error message:</p>
  
  <pre><code>2013-05-30 16:58:57,329|DEBUG|main|hibernate.cfg.AnnotationBinder||Processing annotations of com.soebes.casestudy.bo.CategoryBO.subCategories
  2013-05-30 16:58:57,329|DEBUG|main|hibernate.cfg.Ejb3Column||Binding column null. Unique false. Nullable true.
  2013-05-30 16:58:57,329|DEBUG|main|hibernate.cfg.Ejb3Column||Binding column subCategories. Unique false. Nullable true.
  2013-05-30 16:58:57,331|DEBUG|main|hibernate.cfg.Ejb3Column||Binding column null. Unique false. Nullable true.
  FAILED: testGet
  org.hibernate.AnnotationException: Illegal attempt to map a non collection as a @OneToMany, @ManyToMany or @CollectionOfElements: com.soebes.casestudy.bo.CategoryBO.subCategories
      at org.hibernate.cfg.annotations.CollectionBinder.getCollectionBinder(CollectionBinder.java:266)
      at org.hibernate.cfg.AnnotationBinder.processElementAnnotations(AnnotationBinder.java:1448)
      at org.hibernate.cfg.AnnotationBinder.bindClass(AnnotationBinder.java:754)
      at org.hibernate.cfg.AnnotationConfiguration.processArtifactsOfType(AnnotationConfiguration.java:546)
      at org.hibernate.cfg.AnnotationConfiguration.secondPassCompile(AnnotationConfiguration.java:291)
      at org.hibernate.cfg.Configuration.buildSessionFactory(Configuration.java:1319)
      at org.hibernate.cfg.AnnotationConfiguration.buildSessionFactory(AnnotationConfiguration.java:867)
      at com.soebes.casestudy.hibernate.HibernateUtil.getSession(HibernateUtil.java:36)
      at com.soebes.casestudy.hibernate.HibernateUtil.beginTransaction(HibernateUtil.java:48)
  </code></pre>
  
  <p>which i don't understand.</p>
  
  <p>So where is my misunderstanding or my problem (I assume something really stupid)...</p>
  
  <p><strong>Update</strong>:</p>
  
  <p>After I have updated the code accordingly to the suggestion in the answer of Jimmy T like this:</p>
  
  <pre><code>@OneToMany(mappedBy = "parent")
  private List&lt;CategoryBO&gt; subCategories;
  </code></pre>
  
  <p>I got the following error messages:</p>
  
  <pre><code>2013-05-30 19:08:33,363|DEBUG|main|hibernate.loader.Loader||done entity load
  2013-05-30 19:08:33,364|INFO|main|event.def.DefaultLoadEventListener||Error performing load command
  org.hibernate.ObjectNotFoundException: No row with the given identifier exists: [com.soebes.casestudy.bo.CategoryBO#0]
      at org.hibernate.impl.SessionFactoryImpl$2.handleEntityNotFound(SessionFactoryImpl.java:449)
      at org.hibernate.event.def.DefaultLoadEventListener.load(DefaultLoadEventListener.java:233)
      at org.hibernate.event.def.DefaultLoadEventListener.proxyOrLoad(DefaultLoadEventListener.java:285)
      at org.hibernate.event.def.DefaultLoadEventListener.onLoad(DefaultLoadEventListener.java:152)
      at org.hibernate.impl.SessionImpl.fireLoad(SessionImpl.java:1080)
      at org.hibernate.impl.SessionImpl.internalLoad(SessionImpl.java:1028)
      at org.hibernate.type.EntityType.resolveIdentifier(EntityType.java:623)
      at org.hibernate.type.EntityType.resolve(EntityType.java:431)
      at org.hibernate.engine.TwoPhaseLoad.initializeEntity(TwoPhaseLoad.java:140)
      at org.hibernate.loader.Loader.initializeEntitiesAndCollections(Loader.java:898)
      at org.hibernate.loader.Loader.doQuery(Loader.java:773)
      at org.hibernate.loader.Loader.doQueryAndInitializeNonLazyCollections(Loader.java:270)
      at org.hibernate.loader.Loader.doList(Loader.java:2449)
      at org.hibernate.loader.Loader.listIgnoreQueryCache(Loader.java:2192)
      at org.hibernate.loader.Loader.list(Loader.java:2187)
      at org.hibernate.loader.criteria.CriteriaLoader.list(CriteriaLoader.java:119)
      at org.hibernate.impl.SessionImpl.list(SessionImpl.java:1706)
      at org.hibernate.impl.CriteriaImpl.list(CriteriaImpl.java:347)
      at com.soebes.casestudy.dao.HibernateDAO.findAll(HibernateDAO.java:68)
      at com.soebes.casestudy.dao.HibernateDAO.get(HibernateDAO.java:75)
      at com.soebes.casestudy.dao.IdDAO.get(IdDAO.java:23)
      at com.soebes.casestudy.CategoryBOTest.testGet(CategoryBOTest.java:26)
      at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
      at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
      at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
      at java.lang.reflect.Method.invoke(Method.java:601)
      at org.testng.internal.MethodInvocationHelper.invokeMethod(MethodInvocationHelper.java:80)
      at org.testng.internal.Invoker.invokeMethod(Invoker.java:714)
      at org.testng.internal.Invoker.invokeTestMethod(Invoker.java:901)
      at org.testng.internal.Invoker.invokeTestMethods(Invoker.java:1231)
      at org.testng.internal.TestMethodWorker.invokeTestMethods(TestMethodWorker.java:128)
      at org.testng.internal.TestMethodWorker.run(TestMethodWorker.java:111)
      at org.testng.TestRunner.privateRun(TestRunner.java:767)
      at org.testng.TestRunner.run(TestRunner.java:617)
      at org.testng.SuiteRunner.runTest(SuiteRunner.java:334)
  </code></pre>
  
  <p>which I assume is caused by the rows where parentId is 0. Which makes sense, cause no category with the categoryid of 0 exists. But the question is: How can i map that to the meaning not having a parent category?</p>
  
  <p><strong>Update</strong></p>
  
  <p>So after updating my definitions in code like this:</p>
  
  <pre><code>@ManyToOne( cascade = { CascadeType.ALL } )
  @JoinColumn(name = "parentid")
  @NotFound(action = NotFoundAction.IGNORE)
  private CategoryBO parent;
  
  @OneToMany(mappedBy = "parent")
  @NotFound(action = NotFoundAction.IGNORE)
  private List&lt;CategoryBO&gt; subCategories;
  </code></pre>
  
  <p>Now i get a list of categories.</p>