Hi, I'm using 3 classes, Person, Student and Relative. Student extends Person, and has a collection of Relatives (it's an object that contains the Student id, the Person id, its relationship, and a field that denotes if the person is responsible for the Student)
In the insertion process, according to the defined GUI, the user fills the Student Data, and provides a list of the Students' Relatives, giving their names, relationship and if they're responsible or not for the student. So the insert must:
- Create the Student object and persist it.
- For each Relative, saveOrUpdate the Person object and persist it. (It may not exist)
- Create the Relative Object which associates both Student and Relative, and persist it.
For some reason, hibernate does things in this order:
- insert into People (... student data with 'S' as discriminator) - Inserts the student
- insert into Relatives ...
- insert into People (... relative data with 'R' as discriminator)
Since familiar is inserted first, the database constraint on Person throws an exception because it hasnt been created yet! I need hibernate to first insert the relative and then the familiar or else it wont work. Naturally, if I remove the not-null constraint hibernate effectively inserts everything right, but not in the order I need.. What could I be doing wrong? :S
Thanks in advance.
Hibernate version: 2.1.6
Mapping documents:
(Relevant parts. XDoclet generated)
Person.hbm.xml
Code:
<class
name="Person"
table="PEOPLE"
dynamic-update="false"
dynamic-insert="false"
select-before-update="false"
discriminator-value="R"
>
<subclass
name="Student"
dynamic-update="false"
dynamic-insert="false"
discriminator-value="S"
>
<set
name="relatives"
lazy="false"
inverse="true"
cascade="save-update"
sort="unsorted"
>
<key
column="ID_STUDENT"
>
</key>
<one-to-many
class="Relative"
/>
</set>
</subclass>
</class>
Relative.hbm.xml
Code:
<class
name="Relative"
table="RELATIVES"
dynamic-update="false"
dynamic-insert="false"
select-before-update="false"
>
<id
name="id"
column="ID"
type="java.lang.Long"
>
<generator class="increment">
<!--
To add non XDoclet generator parameters, create a file named
hibernate-generator-params-Familiar.xml
containing the additional parameters and place it in your merge dir.
-->
</generator>
</id>
<property
name="responsible"
type="java.lang.String"
update="true"
insert="true"
access="property"
column="RESPONSIBLE"
length="1"
/>
<many-to-one
name="student"
class="Student"
cascade="none"
outer-join="auto"
update="true"
insert="true"
access="property"
column="ID_STUDENT"
/>
<many-to-one
name="relative"
class="Person"
cascade="none"
outer-join="auto"
update="true"
insert="true"
access="property"
column="ID_RELATIVE"
/>
<many-to-one
name="relationship"
class="Relationships"
cascade="none"
outer-join="auto"
update="true"
insert="true"
access="property"
column="ID_RELATIONSHIP"
/>
</class>
Code between sessionFactory.openSession() and session.close():Code:
// set contains already created "Relative" objects.
public void updateFamiliares(Student item, HashSet set)
throws HibernateException, BusinessException {
for (Iterator iter = set.iterator(); iter.hasNext();){
// Extract the relative
Relative rel = (Relative) iter.next();
// Extract its Person object
Person per = rel.getRelative();
// Create the Person in the People table:
HibernateUtil.getSession().saveOrUpdate(per);
// Add the relative to the Student
item.addRelative(rel);
// Save the Student
HibernateUtil.getSession().update(item);
}
}
This function is called by another that handles the openSession(), flushSession() and closeSession() functionalities.
Full stack trace of any exception that occurs:(From Jboss server.log)
2004-10-22 21:49:14,956 WARN [net.sf.hibernate.util.JDBCExceptionReporter] SQL Error: 1400, SQLState: 23000
2004-10-22 21:49:14,956 ERROR [net.sf.hibernate.util.JDBCExceptionReporter] ORA-01400: cannot insert NULL into ("DATABASE"."RELATIVES"."ID_RELATIVE")
[/code]