Hi! I'm trying to model a parent/child relationship (as in biological parent) and I just ran into a bit of trouble. I have a unidirectional many-to-one relation from Child to Parent, and as long as I keep my Child and Parent classes separated, it works fine. But when I add a common superclass, i.e. Person (strategy=JOINED), I get an error: "No row with the given identifier exists: [hibertest.Parent#1]" (full stack trace later). Some further investigation reveals that strategy=SINGLE_TABLE works, but I used JOINED. Any clues to what I'm missing/doing wrong?
My three classes are as follows (I'm using Annotations, so no mapping XML).
Code:
@Entity
@Inheritance(strategy=InheritanceType.JOINED)
public class Person {
private Long id;
public Person() {
}
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
}
Code:
@Entity
public class Parent extends Person {
public Parent() {
}
}
Code:
@Entity
public class Child extends Person {
private Parent parent;
public Child() {
}
@ManyToOne
@JoinColumn(name="parentId")
public Parent getParent() {
return parent;
}
public void setParent(Parent parent) {
this.parent = parent;
}
}
In my main(), I have the following:
Code:
Session session = HibernateUtil.getSession();
session.beginTransaction();
Parent p = new Parent();
session.save(p);
Child c = new Child();
c.setParent(p);
session.save(c);
session.getTransaction().commit();
session.close();
session = HibernateUtil.getSession();
session.beginTransaction();
List<Child> children = session.createQuery("from Child").list();
The last line produces the following stacktrace:
Code:
org.hibernate.ObjectNotFoundException: No row with the given identifier exists: [hibertest.Parent#1]
at org.hibernate.impl.SessionFactoryImpl$1.handleEntityNotFound(SessionFactoryImpl.java:375)
at org.hibernate.event.def.DefaultLoadEventListener.load(DefaultLoadEventListener.java:143)
at org.hibernate.event.def.DefaultLoadEventListener.proxyOrLoad(DefaultLoadEventListener.java:193)
at org.hibernate.event.def.DefaultLoadEventListener.onLoad(DefaultLoadEventListener.java:101)
at org.hibernate.impl.SessionImpl.fireLoad(SessionImpl.java:878)
at org.hibernate.impl.SessionImpl.internalLoad(SessionImpl.java:846)
at org.hibernate.type.EntityType.resolveIdentifier(EntityType.java:266)
at org.hibernate.type.EntityType.resolve(EntityType.java:303)
at org.hibernate.engine.TwoPhaseLoad.initializeEntity(TwoPhaseLoad.java:116)
at org.hibernate.loader.Loader.initializeEntitiesAndCollections(Loader.java:842)
at org.hibernate.loader.Loader.doQuery(Loader.java:717)
at org.hibernate.loader.Loader.doQueryAndInitializeNonLazyCollections(Loader.java:224)
at org.hibernate.loader.Loader.doList(Loader.java:2144)
at org.hibernate.loader.Loader.listIgnoreQueryCache(Loader.java:2028)
at org.hibernate.loader.Loader.list(Loader.java:2023)
at org.hibernate.loader.hql.QueryLoader.list(QueryLoader.java:393)
at org.hibernate.hql.ast.QueryTranslatorImpl.list(QueryTranslatorImpl.java:338)
at org.hibernate.engine.query.HQLQueryPlan.performList(HQLQueryPlan.java:172)
at org.hibernate.impl.SessionImpl.list(SessionImpl.java:1121)
at org.hibernate.impl.QueryImpl.list(QueryImpl.java:79)
at hibertest.Main.main(Main.java:46)
The SQL generated is
Code:
insert into Person values ( )
insert into Parent (id) values (?)
insert into Person values ( )
insert into Child (parentId, id) values (?, ?)
select child0_.id as id0_, child0_.parentId as parentId1_ from Child child0_ inner join Person child0_1_ on child0_.id=child0_1_.id
select parent0_.id as id0_0_ from Parent parent0_ inner join Person parent0_1_ on parent0_.id=parent0_1_.id where parent0_.id=?
If I remove the Person class and copy the id attribute with getter/setter to the Child and Parent classes, the code works. And if I instead change the inheritance strategy to SINGLE_TABLE it also works.
I'm using Hibernate3.2 with Hibernate Annotations. I'm using JDK 1.5_06 on Windows. My DB is MySql 4.1.11 on Fedora Core 4.
Cheers,
/ Mats