• Open Menu Close Menu
  • Apple
  • Shopping Bag
  • Apple
  • Mac
  • iPad
  • iPhone
  • Watch
  • TV
  • Music
  • Support
  • Search apple.com
  • Shopping Bag

Lists

Open Menu Close Menu
  • Terms and Conditions
  • Lists hosted on this site
  • Email the Postmaster
  • Tips for posting to public mailing lists
Re: DatabaseContextDelegate + Compound Primary Keys that Include Foreign Keys (+INHERITANCE!!!)
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: DatabaseContextDelegate + Compound Primary Keys that Include Foreign Keys (+INHERITANCE!!!)


  • Subject: Re: DatabaseContextDelegate + Compound Primary Keys that Include Foreign Keys (+INHERITANCE!!!)
  • From: Robert B.Hanviriyapunt <email@hidden>
  • Date: Fri, 13 Jun 2008 12:03:46 -0500

Yes it seems the problem lies in the sub-relationship entity:

Company --(relationships[propagatesKeys=Y])-->> Product

SubProduct is a sub-entity to Product
thus:
Company <--(parent[cpkFkCompanyID])-- Product
Company <--(parent[cpkFkCompanyID])-- SubProduct

I have a sample project that illustrates this.

My attempts to determine what is actually happening has led me to a few conclusions:

On a normal toMany (no inheritance), it works because primary keys are resolved IN-ORDER based on propagates.

Once you introduce the inheritance on the destination object, it fails to get primary keys ...

It seems that it does not resolve the primary keys in-order because it does not respect or perhaps not know about the propagates to the sub-entity.

On Jun 11, 2008, at 1:34 PM, Robert B. Hanviriyapunt wrote:

Yep. I figured that out yesterday (that I needed to set propagate on all child/parent-relationships in sub-entities to Person. But I still get the error about the EmployerEmployeeRelationship not getting a primary key. I'm still verifying/investigating tho.

Thanks for helping btw.  :D

= Robert =

On Jun 11, 2008, at 1:16 PM, Chuck Hill wrote:


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@hidden>

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.primaryKeyDictionaryForObjectAndPrimar yKeyAttributes: ";


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.primaryKeyDictionaryForObjectAndPrimary KeyAttributes: attributeName = cpkFkCompanyID ... no value from EO ... setting gotAllKeys to FALSE
[2008-06-10 11:18:33 CDT] <main> DatabaseContextDelegate1.primaryKeyDictionaryForObjectAndPrimary KeyAttributes: 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.primaryKeyDictionaryForObjectAndPrimary KeyAttributes:
<-- (1) DatabaseContextDelegate1.databaseContextNewPrimaryKey:
[2008-06-10 11:18:33 CDT] <main> A fatal exception occurred: Adaptor com.webobjects.jdbcadaptor.JDBCAdaptor@609812 failed to provide new primary keys for entity 'Product'
[2008-06-10 11:18:33 CDT] <main> java.lang.IllegalStateException: Adaptor com.webobjects.jdbcadaptor.JDBCAdaptor@609812 failed to provide new primary keys for entity 'Product'
at com.webobjects.eoaccess.EODatabaseContext.prepareForSaveWithCoor dinator(EODatabaseContext.java:5885)
at com.webobjects.eocontrol.EOObjectStoreCoordinator.saveChangesInE ditingContext(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@hidden)
Help/Unsubscribe/Update your Subscription:
40global-village.net


This email sent to email@hidden

--

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@hidden) Help/Unsubscribe/Update your Subscription: This email sent to email@hidden
  • Follow-Ups:
    • To Many to EOs w/ Compound Primary Keys that Include Reverse Foreign Key (+INHERITANCE!!!) -- FIX / WORK-AROUND
      • From: Robert B.Hanviriyapunt <email@hidden>
References: 
 >Re: DatabaseContextDelegate + Compound Primary Keys that Include Foreign Keys (From: Robert B.Hanviriyapunt <email@hidden>)
 >Fwd: DatabaseContextDelegate + Compound Primary Keys that Include Foreign Keys (+INHERITANCE!!!) (From: Robert B.Hanviriyapunt <email@hidden>)
 >Re: DatabaseContextDelegate + Compound Primary Keys that Include Foreign Keys (+INHERITANCE!!!) (From: Chuck Hill <email@hidden>)
 >Re: DatabaseContextDelegate + Compound Primary Keys that Include Foreign Keys (+INHERITANCE!!!) (From: "Robert B. Hanviriyapunt" <email@hidden>)

  • Prev by Date: Re: Fluffy Bunny + Re: WebObjects Nightly Builds and WOLips addition
  • Next by Date: Reverse engineering database
  • Previous by thread: Re: DatabaseContextDelegate + Compound Primary Keys that Include Foreign Keys (+INHERITANCE!!!)
  • Next by thread: To Many to EOs w/ Compound Primary Keys that Include Reverse Foreign Key (+INHERITANCE!!!) -- FIX / WORK-AROUND
  • Index(es):
    • Date
    • Thread