Java Database Connectivity (JDBC) - Hibernate mapping 3 tables many-to-many problem!

Hi, I've a problem with a many-to-many mapping.

The scenario where I'm working in it's here:

Database Oracle 9

Hibernate 3

Java jdk 1.5.0_09

First of all there is the hbm file of the tables that I've mapped:

Table Gruppi:

<hibernate-mapping>

<class name="com.tiengineering.webapp.users.orm.Gruppo"

table="TABGRUPPI" >

<id name="idgruppo"

type="java.lang.Integer"

column="IDGRUPPO"

unsaved-value="null">

<generator class="sequence">

<param name="sequence">IGruppi</param>

</generator>

</id>

<property name="nomegruppo"

type="java.lang.String"

column="NOMEGRUPPO"

not-null="true"

unique="true"

length="50" >

</property>

<property name="descrizione"

type="java.lang.String"

column="DESCRIZIONE" >

</property>

<!-- Associations -->

<!-- bi-directional many-to-many association to Tabgruppilivelli -->

<set name="livelli"

table="tabgruppilivelli"

lazy="false"

inverse="false"

cascade="all">

<key>

<column name="IDGRUPPO" not-null="true"/>

</key>

<many-to-many class="com.tiengineering.webapp.users.orm.Livello">

<column name="IDLIVELLO" not-null="true"/>

</many-to-many>

</set>

<!-- bi-directional many-to-many association to Tabutentigruppi -->

<set name="utenti"

table="tabutentigruppi"

lazy="false"

inverse="true"

cascade="none">

<key>

<column name="IDGRUPPO" not-null="true"/>

</key>

<many-to-many class="com.tiengineering.webapp.users.orm.Utente">

<column name="IDUTENTE" not-null="true"/>

</many-to-many>

</set>

</class>

</hibernate-mapping>

Table utente:

<hibernate-mapping>

<class name="com.tiengineering.webapp.users.orm.Utente"

table="TABUTENTI">

<id name="idutente"

type="java.lang.Integer"

column="IDUTENTE"

unsaved-value="null">

<generator class="sequence">

<param name="sequence">IUtenti</param>

</generator>

</id>

<property name="userid"

type="java.lang.String"

column="USERID"

not-null="true"

unique="true"

length="50">

</property>

<property name="fullname"

type="java.lang.String"

column="FULLNAME"

not-null="true"

length="200">

</property>

<property name="descrizione"

type="java.lang.String"

column="DESCRIZIONE">

</property>

<!-- Associations -->

<!-- bi-directional many-to-many association to Tabpermessispeciali -->

<set name="permessispeciali"

table="tabpermessispeciali"

lazy="false"

inverse="false"

cascade="all">

<key>

<column name="IDUTENTE" not-null="true"/>

</key>

<many-to-many class="com.tiengineering.webapp.users.orm.Livello">

<column name="IDLIVELLO" not-null="true"/>

</many-to-many>

</set>

<!-- bi-directional many-to-many association to Tabutentigruppi -->

<set name="gruppi"

table="tabutentigruppi"

lazy="false"

inverse="false"

cascade="all">

<key>

<column name="IDUTENTE" not-null="true"/>

</key>

<many-to-many class="com.tiengineering.webapp.users.orm.Gruppo">

<column name="IDGRUPPO" not-null="true"/>

</many-to-many>

</set>

</class>

</hibernate-mapping>

Table Livelli:

<hibernate-mapping>

<class name="com.tiengineering.webapp.users.orm.Livello"

table="TABLIVELLI" >

<id name="idlivello"

type="java.lang.Integer"

column="IDLIVELLO"

unsaved-value="null">

<generator class="sequence">

<param name="sequence">ILivelli</param>

</generator>

</id>

<property name="nomelivello"

type="java.lang.String"

column="NOMELIVELLO"

not-null="true"

unique="true"

length="100">

</property>

<property name="descrizione"

type="java.lang.String"

column="DESCRIZIONE">

</property>

<!-- Associations -->

<!-- bi-directional many-to-many association to Tabgruppilivelli -->

<set name="gruppi"

table="tabgruppilivelli"

lazy="false"

inverse="true"

cascade="none">

<!-- cascade="all" -->

<key>

<column name="IDLIVELLO" not-null="true"/>

</key>

<many-to-many class="com.tiengineering.webapp.users.orm.Gruppo">

<column name="IDGRUPPO" not-null="true"/>

</many-to-many>

</set>

<!-- bi-directional many-to-many association to Tabpermessispeciali -->

<set name="permessispeciali"

table="tabpermessispeciali"

lazy="false"

inverse="true"

cascade="none">

<!-- cascade="all" -->

<key>

<column name="IDLIVELLO" not-null="true"/>

</key>

<many-to-many class="com.tiengineering.webapp.users.orm.Utente">

<column name="IDUTENTE" not-null="true"/>

</many-to-many>

</set>

</class>

</hibernate-mapping>

When I try to save object Utente with a levels and groups it's ok, I've this insert result from hibernate after session.flush and commit of transaction:

Hibernate: select IUtenti.nextval from dual

Hibernate: insert into TABUTENTI (USERID, FULLNAME, DESCRIZIONE, IDUTENTE) values (?, ?, ?, ?)

Hibernate: insert into tabpermessispeciali (IDUTENTE, IDLIVELLO) values (?, ?)

Hibernate: insert into tabpermessispeciali (IDUTENTE, IDLIVELLO) values (?, ?)

Hibernate: insert into tabutentigruppi (IDUTENTE, IDGRUPPO) values (?, ?)

To save Utente Object I use session.merge();

The problem is when I tried to save a Gruppo with levels:

when I made merge and flush hibernate make this

ernate: select IGruppi.nextval from dual

Hibernate: insert into TABGRUPPI (NOMEGRUPPO, DESCRIZIONE, IDGRUPPO) values (?, ?, ?)

Hibernate: insert into tabgruppilivelli (IDGRUPPO, IDLIVELLO) values (?, ?)

Hibernate: insert into tabgruppilivelli (IDGRUPPO, IDLIVELLO) values (?, ?)

after commit of transaction make a delete and after reinsert in tabgruppilivelli

Hibernate: delete from tabgruppilivelli where IDGRUPPO=?

Hibernate: insert into tabgruppilivelli (IDGRUPPO, IDLIVELLO) values (?, ?)

Hibernate: insert into tabgruppilivelli (IDGRUPPO, IDLIVELLO) values (?, ?)

Data persist in table tabgruppi livelli until I try to get list of guppi, because after querys hibernate make a delete on table gruppilivelli

Hibernate: select utenti0_.IDGRUPPO as IDGRUPPO1_, utenti0_.IDUTENTE as IDUTENTE1_, utente1_.IDUTENTE as IDUTENTE0_0_, utente1_.USERID as USERID0_0_, utente1_.FULLNAME as FULLNAME0_0_, utente1_.DESCRIZIONE as DESCRIZI4_0_0_ from tabutentigruppi utenti0_, TABUTENTI utente1_ where utenti0_.IDUTENTE=utente1_.IDUTENTE(+) and utenti0_.IDGRUPPO=?

Hibernate: select livelli0_.IDGRUPPO as IDGRUPPO1_, livelli0_.IDLIVELLO as IDLIVELLO1_, livello1_.IDLIVELLO as IDLIVELLO5_0_, livello1_.NOMELIVELLO as NOMELIVE2_5_0_, livello1_.DESCRIZIONE as DESCRIZI3_5_0_ from tabgruppilivelli livelli0_, TABLIVELLI livello1_ where livelli0_.IDLIVELLO=livello1_.IDLIVELLO(+) and livelli0_.IDGRUPPO=?

Hibernate: delete from tabgruppilivelli where IDGRUPPO=?

so the data lost and there is no association between gruppi and livelli.

Someone can give me some hint to understand where the problem is?

Thank you for the help.

[8308 byte] By [ChuckNa] at [2007-11-26 23:06:40]
# 1
As far as I can tell without seeing the code, you've almost certainly failed to update the Utente end of the Gruppi-Utente association before trying to save the Gruppi object.
dcmintera at 2007-7-10 14:00:23 > top of Java-index,Database Connectivity,Java Database Connectivity (JDBC)...
# 2

Thank you for the answer. Utente end of Gruppi-Utente association is declared as inverse= false and cascade = all, so I can update, insert, delete only from Utente of Utente-Gruppi association, because I don't want to make operation on Gruppi-Utente from Gruppi but I want that only Utente can make changes.

ChuckNa at 2007-7-10 14:00:23 > top of Java-index,Database Connectivity,Java Database Connectivity (JDBC)...
# 3

You said it didn't save the additional details when you save Gruppi. It won't - because Gruppi doesn't own the associations. Unless you therefore make the change on the Utente side of the association it won't preserve it in the database.

If this isn't what you're talking about, you'll have to express yourself more clearly. Presenting us with the code you're actually talking about instead of a rambling and incoherent "description" of it would help.

dcmintera at 2007-7-10 14:00:23 > top of Java-index,Database Connectivity,Java Database Connectivity (JDBC)...