I just had a look at my test again and I discovered that indeed JPOX
does ignore the delete-action="" for the 1:1 bidirectional
case. So upon deletion, objects will silently be removed from any 1:1
bidirectional relationships, and corresponding FK constraints will
never prevent such a deletion.
I created issue http://www.jpox.org/servlet/jira/browse/CORE-2895 for
this. Unfortunately yesterday I had been looking at the wrong test.
Regards,
Jörg
Jörg von Frantzius schrieb:
Hello Craig,
that did the trick, I'm now seeing my constraint violation as expected,
thanks! So at least the delete-action="" is not ignored.
Maybe the question should be: why does JPOX create FKs by default in
combination with a "SET NULL" deletion
behaviour that is not specified, at least not in the JDO2 spec? MySQL 5
seems to have that behaviour specifiable
in FK constraints. Also I'd bet it doesn't have that behaviour for
one-many relationships, so that's kinda inconsistent also.
Of course it's nice to have FKs created automatically, but then IMHO it
should have a default delete-action="", as that's what you'd
expect when you see a FK in your schema...
Regards,
Jörg
Craig L Russell schrieb:
Hi Jörg,
JDO2 did intend to disallow the behavior you describe.
Additionally, the metadata allows you to explicitly declare
the
behavior of the FK on delete.
You could try explicitly setting the FK delete behavior to
restrict, and see what happens:
<field name="b_1to1" column="b_1to1_FK"
persistence-modifier="persistent" >
<foreign-key delete-action=""/>
</field>
But even without this declaration, I think there is an issue
with the described behavior.
To my recollection, there are no TCK test cases for this.
Craig
On Jul 5, 2006, at 7:36 AM, Jörg von Frantzius wrote:
Hi,
only now I realize that JPOX does some automatic nulling of FKs during
deletePersistent(), i.e. although I have an FK in the database, I'll
never run into a FK violation when deleting a record that is being
referred to!
In my package.jdo I have classes A and B referring to each other in a
1:1 relation:
<class name="AFragment"
identity-type="application"
table="A" detachable="true"
objectid-class="javax.jdo.identity.LongIdentity"
persistence-modifier="persistence-capable">
<inheritance strategy="new-table"/>
<version strategy="version-number"
column="jdoversion"/>
<field name="id" primary-key="true"
persistence-modifier="persistent" value-strategy="sequence"
sequence="A_SEQ" >
<extension vendor-name="jpox"
key="key-database-cache-size" value="100"/>
</field>
<field name="b_1to1" column="b_1to1_FK"
persistence-modifier="persistent" >
</field>
</class>
<class name="BFragment"
identity-type="application"
table="B" detachable="true"
objectid-class="javax.jdo.identity.LongIdentity"
persistence-modifier="persistence-capable">
<inheritance strategy="new-table"/>
<version strategy="version-number"
column="jdoversion"/>
<field name="id" primary-key="true"
persistence-modifier="persistent" value-strategy="sequence"
sequence="B_SEQ" >
<extension vendor-name="jpox"
key="key-database-cache-size" value="100"/>
</field>
<field name="a_1to1" mapped-by="b_1to1"
persistence-modifier="persistent" >
</field>
</class>
So table A has a column b_1to1_FK referring to B.
When I call deletePersistent() for a B object that is being referred to
by an A object, I see the following SQL:
[05 Jul 2006 16:23:46,483] DEBUG Request.java:70 - UPDATE
A SET B_1TO1_FK=NULL WHERE A.B_1TO1_FK=<1> -- 1 PS parameters
[05 Jul 2006 16:23:46,499] DEBUG Request.java:81 - Execution Time = 16
ms
[05 Jul 2006 16:23:58,656] DEBUG Request.java:70 - DELETE FROM B WHERE
ID = <1> -- 1 PS parameters
[05 Jul 2006 16:23:58,671] DEBUG Request.java:81 - Execution Time = 15
ms
The spec says "If deleting an instance would violate datastore
integrity constraints, it is implementation-defined whether an
exception is thrown at commit time, or the delete operation is simply
ignored." JPOX does neither of the two, but implements a third option.
Is this intended to be covered by the spec?
I'd think that this is dangerous behaviour, as the programmer might be
deleting objects without realizing the consequences. If the FK
violations occur, and consequently he must explicitly remove the object
from any existing relation before deleting it, then he knows what
information he is loosing exactly.
Regards,
Jörg
|