Hello Craig,

that did the trick, I'm now seeing my constraint violation as expected, thanks! So at least the delete-action="restrict" 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="restrict", 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="restrict"/>
            </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

Craig Russell

Architect, Sun Java Enterprise System http://java.sun.com/products/jdo

408 276-5638 mailto:Craig.Russell@sun.com

P.S. A good JDO? O, Gasp!