Hi again.
I'm handle a many-to-many relationship with a intermediate class, and I mapped this as two one-to-many associations between three entities.
Alumno --- one-to-many ---> RamoAlumno
Ramo ---- one-to-many ----> RamoAlumno
I use composite-id in RamoAlumno.
My problem is: I can't insert RamoAlumno in the database :(.
Before a commit sentence, relationship works fine, and I can print information.
// p belong to Alumno
for (Iterator it = p.getRamosAlumno().iterator(); it.hasNext();) {
RamoAlumno ram = (RamoAlumno) it.next();
out.println("<p>ramo del alumno:"+ram.getAlumno().getNombre());
out.println("ramo-alumno2:"+ram.getRamo().getNombre());
}
// this print fine
But after commit, I look my database, and RamoAlumno is not persist (don't save it).
Please, I need help. I'm very sad because early I don't use composite-id and I did can insert in database fine, but I can't handle relationship well, because just one work fine (the other is dead :S ), and I guess that is not well. I did write in the forum about that, but was'nt anybody response to me. I'm newbie, I need help, If you want, I'll send you my whole system, with a picture about UML design.
Hibernate version: Hibernate 3.1.3
Mapping documents:
//persona.hbm.xml (Alumno is a subclass)
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
<class name="encuestas.Persona"
table="PERSONA"
lazy="true"
abstract="true">
<id name="id"
type="long"
column="PERSONA_ID"
access="field">
<generator class="native"/>
</id>
<property name="rut"
type="long"
not-null="true">
<column name="RUT"/>
</property>
....
<joined-subclass name="encuestas.Alumno" table="ALUMNO">
<key column="ALUMNO_ID"/>
<property name="password"
type="string"
not-null="true">
<column name="PASSW"/>
</property>
<set name="Formas_rptas"
lazy="true"
inverse="true"
cascade="delete" >
<key>
<column name="alumnoID" />
</key>
<one-to-many class="encuestas.FormaRpta"/>
</set>
<set name="ramosAlumno"
lazy="true"
inverse="true"
cascade="all, delete-orphan"
fetch="subselect"
access="field">
<key foreign-key="FK1_RAMO_ALUMNO_ID">
<column name="alumnoID" not-null="true"/>
</key>
<one-to-many class="encuestas.RamoAlumno"/>
</set>
<!-- It don't allow bidirectional relationship (Ramo-->) because that, I comment it
<set name="ramos" lazy="true" table="ALUMNO_RAMO">
<key column="alumnoID"/>
<composite-element class="encuestas.AlumnoRamo">
<parent name="alumno"/>
<many-to-one name="ramo"
class="encuestas.Ramo"
column="ramoID"
not-null="true"/>
<property name="semestre" column="SEMESTRE" not-null="true"/>
<property name="agno" column="AGNO" not-null="true"/>
<property name="estado" column="ESTADO" not-null="true"/>
</composite-element>
</set> -->
</joined-subclass>
<joined-subclass name="encuestas.Profesor" table="PROFESOR">
<key column="PROFESOR_ID"/>
<property name="tipo"
type="string"
not-null="true">
<column name="TIPO"/>
</property>
<!-- this is my other way to handle many-to-many, but it don't work fine, because I lose Ramo---RamoProfesor relationship -->
<set name="Ramo_profesor"
lazy="true"
inverse="true"
cascade="delete" >
<key>
<column name="profesorID" />
</key>
<one-to-many class="encuestas.RamoProfesor"/>
</set>
</joined-subclass>
</class>
</hibernate-mapping>
Ramo.hbm.xml
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
<class name="encuestas.Ramo" table="RAMO" lazy="true">
<id name="id"
type="long"
column="RAMO_ID"
unsaved-value="null"
access="field">
<generator class="native"/>
</id>
<version name="version"
column="VERSION"
access="org.hibernate.property.DirectPropertyAccessor"/>
<property name="nombre"
type="string"
not-null="true"
access="field">
<column name="NOMBRE"/>
</property>
<property name="numero"
type="int"
not-null="true">
<column name="NUMERO"/>
</property>
...
<!--this don't work in r.getRamoAlumno-->
<set name="Ramo_profesor"
lazy="true"
inverse="true"
cascade="delete" >
<key>
<column name="ramoID" />
</key>
<one-to-many class="encuestas.RamoProfesor"/>
</set>
<!-- I don't know why-->
<set name="ramosAlumno"
lazy="true"
inverse="true"
cascade="all, delete-orphan"
access="field">
<key foreign-key="FK2_RAMO_ALUMNO_ID">
<column name="ramoID" not-null="true"/>
</key>
<one-to-many class="encuestas.RamoAlumno"/>
</set>
<set name="Formas_rptas"
lazy="true"
inverse="true"
cascade="delete" >
<key>
<column name="ramoID" />
</key>
<one-to-many class="encuestas.FormaRpta"/>
</set>
</class>
</hibernate-mapping>
RamoAlumno.hbm.xml
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="encuestas">
<class name="RamoAlumno" table="RAMO_ALUMNO">
<composite-id name="id"
class="RamoAlumno$Id"
access="field">
<key-property name="alumnoId"
access="field"
column="ALUMNO_ID"/>
<key-property name="ramoId"
access="field"
column="RAMO_ID"/>
</composite-id>
<!-- I don't know if Date is set automatic or I need to do that
<property name="fechaTomado"
column="FECHA_TOMADO"
type="timestamp"
not-null="true"
access="field"/> -->
<property name="semestre"
type="string"
not-null="true"
update="false"
access="field">
<column name="SEMESTRE"/>
</property>
<property name="agno"
type="int"
not-null="true"
update="false"
access="field">
<column name="AGNO"/>
</property>
<property name="estado"
type="string"
not-null="true"
access="field">
<column name="ESTADO"/>
</property>
<many-to-one
name="alumno"
column="ALUMNO_ID"
not-null="true"
access="field"
insert="false"
update="false"
/>
<many-to-one
name="ramo"
column="RAMO_ID"
not-null="true"
access="field"
insert="false"
update="false"/>
</class>
</hibernate-mapping>
Code between sessionFactory.openSession() and session.close():
sess.beginTransaction();
Query q = sess.createQuery("from Persona r where r.rut = :rut");
q.setString("rut", rut);
Alumno p = (Alumno) q.uniqueResult();
p.getId();
out.println("<p>nombre alum:"+p.getNombre() +" "+p.getApellido_pat());
for(i=0;i < j;i++){
ids=request.getParameter("ch"+Integer.toString(i+1));
if(ids!=null){
id_ramo=Long.valueOf((ids));
//out.println(" idramo:"+id_ramo);
Ramo r = (Ramo) sess.load(Ramo.class, id_ramo);
nom_ramo = r.getNombre();
out.println("<p>nombre ramo:"+r.getNombre()+" id_ramo:"+r.getId()+"</p>");
RamoAlumno.Id id_ra = new RamoAlumno.Id(p.getId(),r.getId());
RamoAlumno rp = new RamoAlumno();
rp.setId(id_ra);
rp.setAlumno(p);
rp.setRamo(r);
rp.setSemestre(sem);
rp.setAgno(agno);
rp.setEstado(estado);
sess.saveOrUpdate(rp);
//sess.flush(); this don't work :(
out.println("<p>constructor ramo_alumno</p>");
out.println("<p>estado:"+rp.getEstado());
sess.persist(rp);
//sess.saveOrUpdate(rp);
r.getRamosAlumno().add(rp);
out.println("<p>r add ramo_alumno</p>");
p.getRamosAlumno().add(rp);
out.println("<p>p add ramo_alumno</p>");
sess.saveOrUpdate(r);
out.println("<p> save-upd r</p>");
sess.saveOrUpdate(p);
out.println("<p> save-upd p</p>");
}
}
for (Iterator it = p.getRamosAlumno().iterator(); it.hasNext();) {
RamoAlumno ram = (RamoAlumno) it.next();
out.println("<p>ram del al2:"+ram.getAlumno().getNombre());
out.println("ramo-alumno2:"+ram.getRamo().getNombre());
}
sess.getTransaction().commit();
Full stack trace of any exception that occurs:
nothing
Name and version of the database you are using:
Mysql 5.0.22-Debian_0ubuntu6.06.2
The generated SQL (show_sql=true):
Thank you. I hope your help
My email:
panarch@gmail.com