I have a database table that contains a simple relationship between parents and children (categories):
+------------+----------+--------------------+ | 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 |
Now I have created a Hibernate CategoryBO mapping class with the above table (AbstractBaseBO contains only two public methods getId () and setId () ..):
@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<CategoryBO> subCategories = new ArrayList<CetegoryBO>(); ...getter/setters
}
But if I try to get a list of category entries from the database, I get the following error message:
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)
which I do not understand.
So where is my misunderstanding or my problem (I assume something really stupid) ...
Update
After I updated the code as suggested by Jimmy T in the following way:
@OneToMany(mappedBy = "parent") private List<CategoryBO> subCategories;
The following error messages appeared:
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
which I suppose is caused by strings where parentId is 0. This makes sense since there is no category with category 0. But the question is: how can I match this to a value that does not have a parent category?
Update
So, after updating my definitions in the code, for example:
@ManyToOne( cascade = { CascadeType.ALL } ) @JoinColumn(name = "parentid") @NotFound(action = NotFoundAction.IGNORE) private CategoryBO parent; @OneToMany(mappedBy = "parent") @NotFound(action = NotFoundAction.IGNORE) private List<CategoryBO> subCategories;
Now I get a list of categories.