Hibernate on delete cascade

L

Larry Yondespor

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>
 
O

Owen Jacobson

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.
 
L

Larry Yondespor

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>
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,776
Messages
2,569,603
Members
45,189
Latest member
CryptoTaxSoftware

Latest Threads

Top