Hibernate on delete cascade  
Author Message
Larry Yondespor





PostPosted: 2005-3-20 23:37:00 Top

java-programmer, Hibernate on delete cascade I use Hibernate and I am not able to do cascade delete.

After I create a project I have:

select * from project;
uid | name | shortdescription
-----+------+-----------------
1 | nc | NC Web application
(1 row)

After I subscribe to the project I have:

select * from subscription;
uid | account | project | role
-----+---------+---------+------
1 | 1 | 1 | 1
(1 row)



When I delete the project with a simple session.delete

try {
session.delete(project);
session.flush();
} catch (HibernateException e) {...

the row is deleted in the table "project"
but the row stays in table "subscription". Only the column entry "project" is set to null.

select * from subscription;
uid | account | project | role
-----+---------+---------+------
1 | 1 | | 1
(1 row)

I want the row to be deleted, how do I do that?






My two tables one for Projects and one for Subscriptions


<hibernate-mapping>

<class name="org.cobra.persistence.Project" table="project">

<id name="id" column="uid" type="long">
<generator class="increment"/>
</id>

<property name="name">
<column name="name" sql-type="char(32)" not-null="true"/>
</property>

<property name="shortDescription">
<column name="shortDescription" sql-type="char(256)" not-null="true"/>
</property>

<set name="subscriptions" table="subscription" cascade="all-delete-orphan">
<key column="project"/>
<one-to-many class="org.cobra.persistence.Subscription"/>
</set>

<set name="subscriptionsRequested" table="subscriptionRequest" cascade="all-delete-orphan">
<key column="project"/>
<one-to-many class="org.cobra.persistence.SubscriptionRequest"/>
</set>

</class>

</hibernate-mapping>


<hibernate-mapping>

<class name="org.cobra.persistence.Subscription" table="subscription">

<id name="id" column="uid" type="long">
<generator class="increment"/>
</id>

<many-to-one name="account" column="account" cascade="all" class="org.cobra.persistence.Account" />

<many-to-one name="project" column="project" cascade="all" class="org.cobra.persistence.Project" />

<many-to-one name="role" column="role" cascade="all" class="org.cobra.persistence.Role" />

</class>

</hibernate-mapping>
 
Owen Jacobson





PostPosted: 2005-3-21 3:07:00 Top

java-programmer >> Hibernate on delete cascade On Sun, 20 Mar 2005 10:36:47 -0500, Larry Yondespor wrote:

> I use Hibernate and I am not able to do cascade delete.
>
> After I create a project I have:
>
> select * from project;
> uid | name | shortdescription
> -----+------+-----------------
> 1 | nc | NC Web application
> (1 row)
>
> After I subscribe to the project I have:
>
> select * from subscription;
> uid | account | project | role
> -----+---------+---------+------
> 1 | 1 | 1 | 1
> (1 row)
>

Just guessing from the output formatting, but that looks like postgreSQL
-- if so, what does
database$ \d subscription
return? Is the project column actually related to the project table's uid
column at all (REFERENCES project (uid) or similar)? Or is Hibernate
attempting to take responsibility for this itself?

> When I delete the project with a simple session.delete
>
> try {
> session.delete(project);
> session.flush();
> } catch (HibernateException e) {...
>
> the row is deleted in the table "project" but the row stays in table
> "subscription". Only the column entry "project" is set to null.
>
> select * from subscription;
> uid | account | project | role
> -----+---------+---------+------
> 1 | 1 | | 1
> (1 row)
>
> I want the row to be deleted, how do I do that?

Couldn't tell you for Hibernate, but the SQL for the tables should look
something like

create table projects (
uid integer primary key, -- or similar
...
);

create table subscription (
uid integer primary key,
account integer,
project integer references projects (uid) on delete cascade,
role integer
);

The behaviour you're seeing is similar to postgreSQL's 'on delete set
null' option.
 
Larry Yondespor





PostPosted: 2005-3-21 5:15:00 Top

java-programmer >> Hibernate on delete cascade On Sun, 20 Mar 2005 19:07:20 +0000, Owen Jacobson wrote:

> Just guessing from the output formatting, but that looks like postgreSQL
> -- if so, what does
> database$ \d subscription
> return? Is the project column actually related to the project table's uid
> column at all (REFERENCES project (uid) or similar)? Or is Hibernate
> attempting to take responsibility for this itself?

You are right this is postgreSQL.

The content of \d subscription is
=# \d subscription
Table "public.subscription"
Column | Type | Modifiers
---------+--------+-----------
uid | bigint | not null
account | bigint |
project | bigint |
role | bigint |
Indexes:
"subscription_pkey" primary key, btree (uid)
Foreign-key constraints:
"fk1456591ded904b19" FOREIGN KEY (project) REFERENCES project(uid)
"fk1456591db9d38a2d" FOREIGN KEY (account) REFERENCES account(uid)
"fk1456591d358076" FOREIGN KEY (role) REFERENCES role(uid)


> Couldn't tell you for Hibernate, but the SQL for the tables should look
> something like
>
> create table projects (
> uid integer primary key, -- or similar
> ...
> );
>
> create table subscription (
> uid integer primary key,
> account integer,
> project integer references projects (uid) on delete cascade,
> role integer
> );
>
> The behaviour you're seeing is similar to postgreSQL's 'on delete set
> null' option.

Yes that's what I would expect to require but that's not what the
hibernate mapping generates.

In the Hibernate mappings I suspect that my many-to-one and my one-to-many
relationships must tie the primary keys instead of an ordinary
column, as the modified mapping shows below. (I did not test that yet).

<hibernate-mapping>

<class name="org.cobra.persistence.Project" table="project">

<id name="id" column="project_id" type="long">
<generator class="increment"/>
</id>

<property name="name">
<column name="name" sql-type="char(32)" not-null="true"/>
</property>

<property name="shortDescription">
<column name="shortDescription" sql-type="char(256)" not-null="true"/>
</property>

<set name="subscriptions" table="subscription" cascade="all-delete-orphan">
<key column="project_id"/>
<one-to-many class="org.cobra.persistence.Subscription"/>
</set>

<set name="subscriptionsRequested" table="subscriptionRequest" cascade="all-delete-orphan">
<key column="project_id"/>
<one-to-many class="org.cobra.persistence.SubscriptionRequest"/>
</set>

</class>

</hibernate-mapping>


<hibernate-mapping>

<class name="org.cobra.persistence.Subscription" table="subscription">

<id name="id" column="subscription_id" type="long">
<generator class="increment"/>
</id>

<many-to-one name="account" column="account_id" cascade="all"
class="org.cobra.persistence.Account" />

<many-to-one name="project" column="project_id" cascade="all"
class="org.cobra.persistence.Project" />

<many-to-one name="role" column="role_id" cascade="all"
class="org.cobra.persistence.Role" />

</class>

</hibernate-mapping>