It looks like that is, indeed, the problem. I just commented out that
DDL-time check and now it's working fine. I realize that I have nothing
to cover me at run-time, but the situation is not going to come up in my
app. I'll just upgrade when the fix makes it in officially.
Thanks!
-Justin
Satheesh Bandaram wrote:
Hi Justin,
You may be hitting DERBY-338
<http://issues.apache.org/jira/browse/DERBY-338>. I think the problem
there is Derby tries to catch possible conflict in cascade delete
actions at DDL time, when a runtime checking is what is needed. In
your case, you said, you don't expect a conflict at run-time.
There is a partial patch pending for DERBY-338 for long time now. It
is probably out of sync with the code. Do you think that could be the
problem you are seeing? Is there anyway you can define your DDL
without "conflicting actions" as Derby seems to think? Derby also has
triggers, if you could use that for part of your schema.
Satheesh
Justin Patterson wrote:
Hey Derby Users,
I'm designing an application to keep up with my music collection.
It's currently running fine on Hibernate/One$DB until I execute 20k
or so transactions. Then, the JVM runs out of memory. After
profiling it, I determined that the leaks are related to One$DB and
that's just the final straw for me. I submitted some questions to
the One$DB forums, but they're not very active and there doesn't seem
to be a new version forthcoming. So, I'm shopping aroiund for a
better embedded RDBMS and I've heard great things about Derby.
After porting my schema over, I ran into something that's peculiar
(to me, anyway) and I'd appreciate any advice that you can give. My
apologies if this is not Derby-specific, but I didn't have any
problems doing this in my schema with either MySQL or One$DB.
Here are the important snippets from my DDL script (I snipped the
irrelevant columns and tables):
CREATE TABLE playable (
id INTEGER GENERATED ALWAYS AS IDENTITY,
CONSTRAINT pk_playable_id PRIMARY KEY (id)
);
CREATE TABLE track (
id INTEGER,
CONSTRAINT pk_track_id PRIMARY KEY (id),
CONSTRAINT fk_track_id FOREIGN KEY (id) REFERENCES playable_t(id) ON
DELETE CASCADE
);
CREATE TABLE mediafile (
id INTEGER,
trackid INTEGER,
CONSTRAINT pk_mediafile_id PRIMARY KEY (id),
CONSTRAINT fk_mediafile_id FOREIGN KEY (id) REFERENCES
playable_t(id) ON DELETE CASCADE,
CONSTRAINT fk_mediafile_trackid FOREIGN KEY (trackid) REFERENCES
track_t(id) ON DELETE SET NULL
);
When I run that, I get:
ERROR 42915: Foreign Key 'FK_MEDIAFILE_TRACKID' is invalid because
'the delete rule of foreign key must be CASCADE. (The relationship
would cause the table to be delete-connected to the same table
through multiple relationships and such relationships must have the
same delete rule (NO ACTION, RESTRICT or CASCADE).) '
So, I looked it up in the DB2 docs and I understand where the error
is coming from, but I don't see how to design around it. What I want
is to have tracks and mediafiles with unique IDs (across both
tables). The playable table should achieve that. If the parent
playable is deleted, I want the track or mediafile subclass (in
Hibernate/Java terms) to be deleted as well. If the parent track of
a mediafile is deleted, I want the mediafile's trackid to be set to
NULL.
I think that I understand why the delete-connected restriction is
there, but since I have the foreign keys in two separate columns and
the parent rows of any involved track and mediafile rows must be
dependent on different rows in the playable table, I don't think that
it should be an issue for me (logically, anyway).
Can anyone think of a workaround (or a better way to design the
schema)? I thought about using a shared sequence, but that's not
avaiable either.
Thanks for your help!
-Justin