On Jun 11, 2008, at 10:30 AM, Robert B.Hanviriyapunt wrote:

I think I actually HAVE an issue!  But it needs further verification.

Firstly, I forgot to mention versions and stuff.  I'm on WO5.3.

Ok so my situation has more levels of complexity, namely INHERITANCE!

1. My model has child Entities (single-table)
2. I'm dealing with a join/assignment table/Entity (many-to-many)
3. This Entity has child Entities whose primary key generation is failing

So the more exact description of my problem is:

Person <--(parent)-- Relationship --(child)--> Person

MalePerson <--(parent)-- ParentChildRelationship --(child)--> MalePerson

FemalePerson <--(parent)-- ParentChildRelationsihp --(child)--> FemalePerson

MalePerson <--(parent)-- EmployerEmployeeRelationship --(child)--> FemalePerson

Relationship <<--(parentRelationships)-- Person -- (childRelationships)-->> Relationship

This represents the different entities, they are sub-entities of their logical entities, the sub-entities have their 'type' attribute set appropriately, and the generic parent and child relationships are defined at the top-Entity. The Relationship classes are NOT maintained by EOF -- they are the problematic compound primary key entities that are failing to get primary keys in the following code:

        EOEditingContext ec = new EOEditingContext();
MalePerson person1 = EOUtilities.createAndInsertInstance ( ec, "MalePerson" ); FemalePerson person2 = EOUtilities.createAndInsertInstance ( ec, "FemalePerson" ); EmployerEmployeeRelationship relationship = EOUtilities.createAndInsertInstance( ec, "EmployerEmployeeRelationship" ); relationship.addObjectToBothSidesOfRelationshipWithKey ( person1, "parent" ); relationship.addObjectToBothSidesOfRelationshipWithKey ( person2, "child" );
        ec.saveChanges();

So the issue continues.  Still no solution.  Still testing.


It sounds like you have a modeling problem. Are all the relationships class properties? Are the relationships into EmployerEmployeeRelationship marked a Propogate Primary Key?


Chuck



= Robert =

Begin forwarded message:

From: Robert B. Hanviriyapunt <[EMAIL PROTECTED]>

Ok I'm feeling a bit foolish now ... I forgot to check propagates primary key.

Ok I haven't fixed my problem yet ... but i'm gettin there. I still think there's an issue somewhere.

= Robert =

On Jun 10, 2008, at 1:17 PM, Robert B. Hanviriyapunt wrote:

Ok, my bad. I did NOT correctly modify the project to work w/ normal EOF EO_PK_TABLE key generation.

Ok so it is now working w/o the Delegate and w/ straight Integer keys. Will try the a delegate next.

= Robert =

On Jun 10, 2008, at 1:00 PM, Robert B. Hanviriyapunt wrote:

I'm sorry, I know everyone's at WWDC, but I really really really need help on this one! I usually don't ask for help because I can figure most stuff out, but man, this is driving me nuts!

Somebody please ... help! I can be on the phone, do a Yugma, whatever!

= Robert =

On Jun 10, 2008, at 11:53 AM, Robert B. Hanviriyapunt wrote:

Ok I really really hope someone can help me with this problem:

I have an existing database which my app has been coded with a DatabaseContextDelegate to handle primary key generation.

I model all Entities such that primary keys and foreign keys are NOT generated (getters or setters) in the class files.

My DatabaseContextDelegate is as follows:

public class DatabaseContextDelegate1 extends Object {

protected static Object utilValueForKey( Object object, String key )
    {
        try {
return NSKeyValueCoding.Utility.valueForKey ( object, key );
        }

        catch ( NSKeyValueCoding.UnknownKeyException e )
        {
NSLog.err.appendln ( "DatabaseContextDelegate1.utilValueForKey: e = " + e );
            e.printStackTrace();
            NSLog.err.appendln( "returning null ..." );
            return null;
        }
    }


    // --- EODatabaseContext.Delegate methods --

public NSDictionary databaseContextNewPrimaryKey ( EODatabaseContext databaseContext, Object object, EOEntity entity )
    {
String debugPrefix = "DatabaseContextDelegate1.databaseContextNewPrimaryKey: ";

// get primary key attributes (description of them) from entity (description of) requesting new primary key(s) NSArray primaryKeyAttributes = entity.primaryKeyAttributes();

        // if *NOT* EXACTLY ONE primary key attribute,
// return primary key dictionary for object and primary key attributes // NOTE: may return null if object does not have values for ALL primary key attributes, thus // allowing someone else (superclass) to handle primary keys
        if ( primaryKeyAttributes.count() != 1 )
        {
            NSDictionary primaryKeyDictionary =
primaryKeyDictionaryForObjectAndPrimaryKeyAttributes( object, primaryKeyAttributes );
            return primaryKeyDictionary;
        }

// NOTE: at this point primary key attributes contain EXACTLY ONE primary key attribute // get description of first (and only) primary key attribute EOAttribute primaryKeyAttribute = (EOAttribute) primaryKeyAttributes.objectAtIndex(0);

if ( primaryKeyAttribute.adaptorValueType() != EOAttribute.AdaptorBytesType )
        {
            // We support only number keys, so call the superclass
            return null;
        }

        // setup variables for further processing
        EOAdaptorChannel channel = null;
        NSDictionary primaryKeyDictionary = null;

        try
        {
            databaseContext.lock();
channel = databaseContext.availableChannel ().adaptorChannel();
            if ( ! channel.isOpen() )
                channel.openChannel();
            NSDictionary row = null;
            try
            {
                EOSQLExpressionFactory factory =
new EOSQLExpressionFactory ( databaseContext.adaptorContext().adaptor() ); EOSQLExpression getRowExpr = factory.expressionForString( "SELECT top 1 VALUE FROM vNewUUID" );
                channel.evaluateExpression( getRowExpr );
                row = channel.fetchRow();
                channel.cancelFetch();
            }

            catch ( Throwable localException ) {
                channel.cancelFetch();
            }

            if ( row != null )
            {
NSData newUUID = (NSData)row.objectForKey ( "VALUE" );
                if ( newUUID != null )
primaryKeyDictionary = new NSDictionary ( (Object)newUUID, (Object)primaryKeyAttribute.name() );
                else
NSLog.err.appendln( debugPrefix + "got NULL newUUID for object " + object );
            }

else NSLog.err.appendln( debugPrefix + "could not set keys for object " + object );
        }

        catch ( Throwable ex ) {
            System.err.println( ex.toString() );
        }

        finally
        {
            if ( channel.isOpen() && channel.isFetchInProgress() )
                channel.cancelFetch();

            databaseContext.unlock();
        }

// NOTE: may return null allowing someone else (superclass) to handle primary keys
        return primaryKeyDictionary;
    }


    // --- utility ---

public NSDictionary primaryKeyDictionaryForObjectAndPrimaryKeyAttributes( Object object, NSArray primaryKeyAttributes )
    {
String debugPrefix = "DatabaseContextDelegate1.primaryKeyDictionaryForObjectAndPrimaryK eyAttributes: ";

int primaryKeyAttributeCount = primaryKeyAttributes.count();

// initialize "got all keys" to TRUE (to be set to FALSE if one is found missing)
        boolean gotAllKeys = true;

        // initialize empty primary key dictionary
NSMutableDictionary primaryKeyDictionary = new NSMutableDictionary();

        // loop thru primary key attributes
        for ( int x = 0 ; x < primaryKeyAttributeCount ; x++ )
        {
            // get next (primary key) attribute
EOAttribute attribute = (EOAttribute) primaryKeyAttributes.objectAtIndex(x);
            // get attribute name
            String attributeName = attribute.name();
// get value from object for attribute by attribute name Object valueFromEO = utilValueForKey( object, attributeName ); // if the object has a value, add it to the primary key dictionary
            // otherwise, flag "got all keys" as FALSE
            if ( valueFromEO != null )
primaryKeyDictionary.setObjectForKey ( valueFromEO, attributeName );
            else
            {
System.out.println( debugPrefix + "attributeName = " + attributeName + " ... no value from EO ... setting gotAllKeys to FALSE" );
                gotAllKeys = false;
            }
        }

        // if we got values for ALL keys from the object,
        // return the primary key dictionary
        if ( gotAllKeys )
        {
NSLog.debug.appendln( debugPrefix + "returning primary key " + primaryKeyDictionary + " from object " + object );
            return primaryKeyDictionary;
        }

// NOTE: at this point we did NOT get values for ALL keys from the object ... // We support only simple primary keys, data keys are handled by superclass // thus DO NOT return the primary key dictionary, instead return NULL (nothing) NSLog.err.appendln( debugPrefix + "could not set keys for object " + object );
        return null;
    }

}

It's all straight forward and works for single primary keys. Where it has problems is when a compound primary key element is a foreign key (a relationship). I think I need the primaryKeyDictionaryForObjectAndPrimaryKeyAttributes function to correctly build the primary key dictionary, but I don't know how to do it, especially with the primary key components being foreign keys (used in relationships that are set, of course). I simplified the test case:

Company:
pkID (binary)
*name (String)

Product:
cpkFkCompanyID (binary)
*cpkCode (String)
*name (String)

*only these items have diamonds on them in EOModeler

Company <--->> Product
default Product. cpkCode value is "xxx"

EODatabaseContext.setDefaultDelegate( new DatabaseContextDelegate1() );
        EOEditingContext ec = new EOEditingContext();
EOEnterpriseObject company = EOUtilities.createAndInsertInstance( ec, "Company" ); EOEnterpriseObject product = EOUtilities.createAndInsertInstance( ec, "Product" ); product.addObjectToBothSidesOfRelationshipWithKey ( company, "company" );
        product.takeValueForKey( "xxx", "cpkCode" );
        ec.saveChanges();

Sounds simple enough right?

Here's my error:

DatabaseContextDelegate1.primaryKeyDictionaryForObjectAndPrimaryKe yAttributes: attributeName = cpkFkCompanyID ... no value from EO ... setting gotAllKeys to FALSE [2008-06-10 11:18:33 CDT] <main> DatabaseContextDelegate1.primaryKeyDictionaryForObjectAndPrimaryKe yAttributes: could not set keys for object {values = {Company = "<com.webobjects.eocontrol.EOGenericRecord e2350a <EOTemporaryGlobalID: 0 0 -64 -88 2 1 0 0 -40 42 1 0 0 0 1 26 115 69 -122 118 -65 -101 100 1>>"; cpkCode = "xxx"; }; this = "<com.webobjects.eocontrol.EOGenericRecord abcd5e <EOTemporaryGlobalID: 0 0 -64 -88 2 1 0 0 -40 42 2 0 0 0 1 26 115 69 -122 118 -65 -101 100 1>>"; } <-- (2) DatabaseContextDelegate1.primaryKeyDictionaryForObjectAndPrimaryKe yAttributes:
<-- (1) DatabaseContextDelegate1.databaseContextNewPrimaryKey:
[2008-06-10 11:18:33 CDT] <main> A fatal exception occurred: Adaptor [EMAIL PROTECTED] failed to provide new primary keys for entity 'Product' [2008-06-10 11:18:33 CDT] <main> java.lang.IllegalStateException: Adaptor [EMAIL PROTECTED] failed to provide new primary keys for entity 'Product' at com.webobjects.eoaccess.EODatabaseContext.prepareForSaveWithCoordi nator(EODatabaseContext.java:5885) at com.webobjects.eocontrol.EOObjectStoreCoordinator.saveChangesInEdi tingContext(EOObjectStoreCoordinator.java:409) at com.webobjects.eocontrol.EOEditingContext.saveChanges (EOEditingContext.java:3226)
        at Application.<init>(Application.java:31)
at sun.reflect.NativeConstructorAccessorImpl.newInstance0 (Native Method) at sun.reflect.NativeConstructorAccessorImpl.newInstance (NativeConstructorAccessorImpl.java:39) at sun.reflect.DelegatingConstructorAccessorImpl.newInstance (DelegatingConstructorAccessorImpl.java:27) at java.lang.reflect.Constructor.newInstance(Constructor.java: 494)
        at java.lang.Class.newInstance0(Class.java:350)
        at java.lang.Class.newInstance(Class.java:303)
at com.webobjects.appserver.WOApplication.main (WOApplication.java:323)
        at Application.main(Application.java:16)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke (NativeMethodAccessorImpl.java:39) at sun.reflect.DelegatingMethodAccessorImpl.invoke (DelegatingMethodAccessorImpl.java:25)
        at java.lang.reflect.Method.invoke(Method.java:585)
at com.webobjects._bootstrap.WOBootstrap.main(WOBootstrap.java: 71)

If anyone has ANY suggestions, please email me as soon as possible!

Thanks!

= Robert =




 _______________________________________________
Do not post admin requests to the list. They will be ignored.
Webobjects-dev mailing list      ([email protected])
Help/Unsubscribe/Update your Subscription:
http://lists.apple.com/mailman/options/webobjects-dev/chill% 40global-village.net

This email sent to [EMAIL PROTECTED]

--

Practical WebObjects - for developers who want to increase their overall knowledge of WebObjects or who are trying to solve specific problems.
http://www.global-village.net/products/practical_webobjects





_______________________________________________
Do not post admin requests to the list. They will be ignored.
Webobjects-dev mailing list      ([email protected])
Help/Unsubscribe/Update your Subscription:
http://lists.apple.com/mailman/options/webobjects-dev/archive%40mail-archive.com

This email sent to [EMAIL PROTECTED]

Reply via email to