Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

...

Here's a method that works for EOs which have a single Integer primary key, to pull out that pk value, and without resolving a fault (possibly causing a trip to the db) when called on a fault value:

unmigrated-wiki-markup
Panel
Code Block

public static Integer singleIntegerPrimaryKeyForObject(EOEnterpriseObject eo) {
    
EOEditingContext ec = eo.editingContext();
    
if (ec == null) {
        //you don't have an EC!
_
 Bad
_
 EO.
_
 We
_
 can
_
 do
_
 nothing.
_ ____________return_null; ________} ________EOGlobalID_gid_=_
 
        return null;
    }
    EOGlobalID gid = ec.globalIDForObject(eo);
________if_
    if (gid.isTemporary())
_{ ____________
 {
        //no
_
 pk
_
 yet
_assigned ____________return_null; ________} ________EOKeyGlobalID_kGid_=_(EOKeyGlobalID)_gid; ________NSArray_keyValues_=_
 assigned
        return null;
    }
    EOKeyGlobalID kGid = (EOKeyGlobalID) gid;
    NSArray keyValues = kGid.keyValuesArray();
________if_
    if (keyValues.count()
_
 != 1 ||
        ! 
!_
(keyValues.objectAtIndex(0)
_
 instanceof
_
 Integer))
____________return_
        return null;
__ ________return_
 
    return (Integer)
_
 keyValues.objectAtIndex(0);
________ ____
       
}

You _ can _ also _ use _ the _ EOUtilities _ method _ but _ please _ note _ that, _ at _ least _ as _ of _ WO5, _ there _ are _ two _ somewhat _ undesirable _ aspects _ of _ this _ EOUtilities _ code:

  • _If _ the _ EO _ is _ a _ fault, _ calling _ the _ EOUtilities _ method _ will _ cause _ the _ fault _ to _ be _ resolved, _ possibly _ requiring _ a _ trip _ to _ the _ db, _ even _ though _ pk _ info _ is _ already _ present _ in _ the _ fault _ and _ the _ trip _ to _ the _ db _ is _ really _ unneccesary _ at _ this _ point.
  • If _ the _ EO _ has _ just _ been _ inserted _ and _ not _ yet _ committed, _ it _ does _ not _ have _ a _ pk _ yet, _ and _ the _ EOUtilities _ code _ will _ throw _ an _ exception. _ And _ it's _ not _ a _ logical _ exception _ corresponding _ to "no _ pk _ yet", _ but _ rather _ some _ uncaught _ exception _ thrown _ by _ some _ surprised _ Apple _ code.

...

Assigning

...

Primary

...

Keys

Wiki Markup
Usually
_
 EOF
_
 doesn't
_
 get
_
 around
_
 to
_
 generating/inserting
_
 primary
_
 keys
_
 until
_
 you
_
 actually
_
 saveChanges() on
_
 an
_
 EOEditingContext
_
 containing
_
 newly
_
 created
_
 about-to-be
_
 saved
_
 EOEnterpriseObjects.

But
_
 sometimes
_
 you
_
 want
_
 to
_
 assign
_
 a
_
 permanent
_
 pk
_
 as
_
 soon
_
 as
_
 you
_
 create
_
 the
_
 EOEnterpriseObject, not
_
 wait
_
 until
_
 it's
_
 actually
_
 committed
_
 to
_
 the
_
 db.
_
 Here's
_
 some
_
 code
_
 to
_
 do
_
 that,
_
 which,
_
 in
_
 a
_
 given
_
 situation,
_
 will
_
 generate
_
 the
_
 pk
_
 in
_
 the
_
 same
_
 way
_
 that
_
 EOF
_
 would
_
 have
_
 generated
_
 it
_
 later,
_
 but
_
 do
_
 it
_
 right
_
 away. \[Thanks
_
 to
_
 Pierre
_
 Barnard\]

__public_void__
Panel
Wiki Markup
Code Block

public void _insertObjectWithGlobalID(EOEnterpriseObject
_
 eo,
_
 EOGlobalID
_
 globalID)
__
 {
____EOEntity_entity_=_
   EOEntity entity = EOUtilities.entityNamed(this,
_
 eo.entityName());
____EODatabaseContext_dbContext_=_
   EODatabaseContext dbContext = EOUtilities.databaseContextForModelNamed(this,
_
 entity.model().name());
____NSDictionary_pkDict_=_
   NSDictionary pkDict = primaryKeyDictionaryForDatabaseContextAndEntity(dbContext,
_
 entity);
________________ ____if_(pkDict_==_null_||_
               
   if (pkDict == null || pkDict.count()
_
 != 1)
   
{
     
NSLog.err.appendln("Failed to generate primary key for entity " + entity.name() + ", or pk is compound.");
   
} else
   
{
     
Object pk = pkDict.allValues().lastObject();
     
globalID = EOKeyGlobalID.globalIDWithEntityName(entity.name(), new Object[] { pk });
   
}
     

   
super._insertObjectWithGlobalID(eo, globalID);
 }
 
 
public static NSDictionary primaryKeyDictionaryForDatabaseContextAndEntity(EODatabaseContext dbContext, EOEntity entity) {
   
NSDictionary pk = null;
   
try {
     
dbContext.lock();
     
EOAdaptorChannel adaptorChannel = dbContext.availableChannel().adaptorChannel();
     
if (!adaptorChannel.isOpen()) {
       adaptorChannel.openChannel();
     }
     
pk = (NSDictionary) adaptorChannel.primaryKeysForNewRowsWithEntity(1, entity).lastObject();
   }
   catch (Exception e) {
     
NSLog.err.appendln("Can't get primary keys for entity " + entity.name() + "  " + e);
   
}
   
finally {
     
dbContext.unlock();
     
return pk;
   
}
 }

There are 2 insertObjectWithGlobalID methods in EOEditingContext. One has a name prefixed by an underscore. The regular one seems to call that one. For most uses overriding the regular one should be sufficient. With JavaClient however, the regular one is not called. On the server side only the one with the underscore is called. You'll have to override the method with the underscore in the server side context as the above will work only on the server.

...