I have a database table which contains a simple self parent/child relationship (categories) like this:
+------------+----------+--------------------+
| 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've created a Hibernate mapping class CategoryBO with the above Table like this (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 the 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 don't understand.
So where is my misunderstanding or my problem (I assume something really stupid)...
Update:
After I have updated the code accordingly to the suggestion in the answer of Jimmy T like this:
@OneToMany(mappedBy = "parent")
private List<CategoryBO> subCategories;
I got the following error messages:
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)
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?
Update
So after updating my definitions in code like this:
@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.
1 Answer. Parent child relationship is established in Hierarchical database Models.
In database management, a relationship between two files. The parent file contains required data about a subject, such as employees and customers. The child is the offspring; for example, an order is the child to the customer, who is the parent.
ServiceNow provides OOTB Parent child relationship. On the incident form Right click on the header and click on the Create Child Incident option. Mark Helpful or correct if it helps.
You should use List
instead of ArrayList
.
Hibernate may put in another List-implementation to support lazy loading.
EDIT: You also have to use NULL
instead of 0
because otherwise Hibernate searches for the object with the id 0.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With