• 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: caching global IDs does not work as expected (followup: ordered and filtered fault efficiency)
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: caching global IDs does not work as expected (followup: ordered and filtered fault efficiency)


  • Subject: Re: caching global IDs does not work as expected (followup: ordered and filtered fault efficiency)
  • From: Chuck Hill <email@hidden>
  • Date: Sun, 15 Feb 2015 20:07:46 +0000
  • Thread-topic: caching global IDs does not work as expected (followup: ordered and filtered fault efficiency)

Hi,

On 2015-02-14, 11:59 PM, "OC" wrote:
On 15. 2. 2015, at 1:48, Chuck Hill <email@hidden> wrote:

===
     private static Map _lastValidPOCacheGID=[:]
     public DBPriceOffer lastValidPriceOffer { // this might happen in any EC, default or temporary
         if (_lastValidPOCacheGID[this.permanentGlobalID()]) {
             def gid=_lastValidPOCacheGID[this.permanentGlobalID()]
             def lvpo=this.editingContext().objectForGlobalID(gid) //1 finds it if exists in EC, or...
Don’t do it like this.  Use ec.faultForGlobalD().  This handles the three cases:

That was the first thing I tried, but with faultForGlobalD(), I

(a) get a fault instead of the object itself -- this is self-evidently wrong, for the object has been added into the EC short time ago, and the documentation says “If the object associated with globalID is already registered in this EOEditingContext ... this method returns that object”

The fault is the EO, or should be. 
public interface EOEnterpriseObject
extends Serializable, EOKeyValueCodingAdditions, EORelationshipManipulation, EOValidation, EODeferredFaulting
EODeferredFaulting extends EOFaulting

 If it is not in the EC, it will return true to isFault() but calling willRead() will fire the fault, populating the data in the EC.  If the object was added to the EC, then it should be returned.  If it is not, then something in your app is very, very, very wrong.  I am also starting to suspect this from some of your other messages.


(b) as probably a direct result of (a), I keep getting databaseContextFailedToFetchObject delegate calls when the fault is fired.

That is insane.


If I don't do anything and return false from the delegate method, I then get the right object, but I feel something is wrong whenever databaseContextFailedToFetchObject comes -- or is it the normal processing here?

Very not normal.   It not even normal to try and fetch it if it has been added to the EC already.  It should only fetch if the snapshot is not there or the timestamp on the snapshot is before the EC’s fetchTimestamp.

If so, how do I distinguish in my delegate method that „this is OK“ from the cases where there's something really amiss?

When using e.g., this code:

=== if I use this code ===
            def gid=DBAuction._lastValidPOCacheGID[this.permanentGlobalID()]
println "???? about to get $gid of $this /EC:${this.editingContext().hashCode()}"
            def lvpo=this.editingContext().faultForGlobalID(gid,this.editingContext())
println "???? got ${lvpo.hashCode()} isfault: ${lvpo.isFault()}"
println "???? -> $lvpo"
===

and, just to repeat for reference,

===
       DBPriceOffer npo=new DBPriceOffer()
       this.editingContext.insertObject(npo)
println "???? setting new valid PO of ${this.permanentGlobalID()}: $npo -> ${npo.permanentGlobalID()} IN.this ${this.editingContext.hashCode()} IN.po ${npo.editingContext.hashCode()}"
===

along with

===
    boolean databaseContextFailedToFetchObject(EODatabaseContext ctxt, Object object, EOGlobalID gid) {
        println "SPC: failed-to-fetch $gid ($object / ${object.getClass()}), missing ${ctxt.missingObjectGlobalIDs()}"
        false
    }
===

for new price order I get this result:

===
???? setting new valid PO of _EOIntegralKeyGlobalID[DBAuction (java.lang.Integer)1000015]: <DBPriceOffer@351793642 PK:null N /EC:1655327563> -> _EOIntegralKeyGlobalID[DBPriceOffer (java.lang.Integer)1000275] IN.this 1655327563 IN.po 1655327563
...
???? about to get _EOIntegralKeyGlobalID[DBPriceOffer (java.lang.Integer)1000275] of <DBAuction@422562876 PK:1000015 E:2 Title:'blah' /EC:1655327563> /EC:1655327563
???? got 1165696376 isfault: true
08:18:48.470 DEBUG  === Begin Internal Transaction
08:18:48.470 DEBUG  evaluateExpression: <com.webobjects.jdbcadaptor.FrontbasePlugIn$FrontbaseExpression: "SELECT t0."C_AMOUNT", t0."C_AUCTION_ID", t0."C_COMM_PARTNER_ID", t0."C_CREATION_DATE", t0."C_CREATOR_ID", t0."C_PRICE", t0."C_PT_ID", t0."C_SHEET_CONFIRMED", t0."C_UID", t0."C_VALID_OFFER" FROM "T_PRICE_OFFER" t0 WHERE t0."C_UID" = 1000275" withBindings: >
08:18:48.471 DEBUG 0 row(s) processed
08:18:48.473 DEBUG  === Commit Internal Transaction
SPC: failed-to-fetch _EOIntegralKeyGlobalID[DBPriceOffer (java.lang.Integer)1000275] (<DBPriceOffer@1165696376 PK:1000275 /EC:1655327563> / class model.DBPriceOffer), missing []
???? -> <DBPriceOffer@1165696376 PK:1000275 /EC:1655327563>
===

???? setting new valid PO of [DBAuction.1000015]: <DBPriceOffer@34841915 PK:null N /EC:73728309> -> [DBPriceOffer.1000206] IN.this 73728309 IN.po 73728309
Why does it say PK:null?   If a permanent GID has been assigned, should be PK not have a value?  And it is null, then null is getting cached here _lastValidPOCacheGID[this.permanentGlobalID()]=npo.permanentGlobalID()   Which I think explains why it is neither found in the EC or fetched?

Well search me. Perhaps this is the gist of the problem? I thought it is normal for the PK to be null until saved to DB; anyway, if I fall back from faultForGlobalID to my hack[*], then this code:

Is permanentGlobalID something that you wrote?  The global ID is based on the PK so the PK value must be known.  Are you creating the GID with the PK but not setting it on the EO?  That might cause EOF to generate a different PK when you save and then GID != PK value which could lead to some of the results you are seeing.  Wonder does this correctly, check the implementation there.

I will try and find time to read more later.

Chuck



===
println "po PK:${po.primaryKeyNumericValue()} / WPK:${po.primaryKey()}"
println "po perm: ${po.permanentGlobalID()}"
println "po PK:${po.primaryKeyNumericValue()} / WPK:${po.primaryKey()}"
println "???? setting found last valid PO of ${this.permanentGlobalID()}: $po -> ${po.permanentGlobalID()} IN ${po.editingContext.hashCode()}"
===

logs out these results:

===
???? setting new valid PO of _EOIntegralKeyGlobalID[DBAuction (java.lang.Integer)1000015]: <DBPriceOffer@522270846 PK:null N /EC:813009222> -> _EOIntegralKeyGlobalID[DBPriceOffer (java.lang.Integer)1000277] IN.this 813009222 IN.po 813009222
08:51:26.236 DEBUG  === Begin Internal Transaction       //log:NSLog [WorkerThread0]
08:51:26.236 DEBUG  evaluateExpression: <com.webobjects.jdbcadaptor.FrontbasePlugIn$FrontbaseExpression: "SELECT t0."C_AMOUNT", t0."C_AUCTION_ID", t0."C_COMM_PARTNER_ID", t0."C_CREATION_DATE", t0."C_CREATOR_ID", t0."C_PRICE", t0."C_PT_ID", t0."C_SHEET_CONFIRMED", t0."C_UID", t0."C_VALID_OFFER" FROM "T_PRICE_OFFER" t0 WHERE t0."C_UID" = 1000277" withBindings: >       //log:NSLog [WorkerThread0]
08:51:26.245 DEBUG 0 row(s) processed       //log:NSLog [WorkerThread0]
08:51:26.443 DEBUG  === Commit Internal Transaction       //log:NSLog [WorkerThread0]
???? fetched valid PO of _EOIntegralKeyGlobalID[DBAuction (java.lang.Integer)1000015]: _EOIntegralKeyGlobalID[DBPriceOffer (java.lang.Integer)1000277] -> null IN 813009222
po PK:-2 / WPK:null
po perm: _EOIntegralKeyGlobalID[DBPriceOffer (java.lang.Integer)1000277]
po PK:-2 / WPK:null
???? setting found last valid PO of _EOIntegralKeyGlobalID[DBAuction (java.lang.Integer)1000015]: <DBPriceOffer@522270846 PK:null N /EC:813009222> -> _EOIntegralKeyGlobalID[DBPriceOffer (java.lang.Integer)1000277] IN 813009222
===

where PK/primaryKeyNumericValue is my ancient pre-Wonder primary key code, which I have re-surrected for reference:

===
    int primaryKeyNumericValue {
        EOEditingContext ec=editingContext();
        if (ec==nil) return -1; // not yet inserted
        EOGlobalID gid=ec.globalIDForObject(this);
        if (gid==nil || gid.isTemporary()) return -2; // not yet assigned
        NSArray kvs=((EOKeyGlobalID)gid).keyValuesArray();
        if (kvs==nil || kvs.count()!=1) return -3; // not single PK, never happens in my model
        Object k=kvs.objectAtIndex(0);
        if (!(k instanceof Integer)) return -3; // not integer PK, never happens in my model
        return ((Integer)k).intValue();
    }
===

Thanks for any isight,
OC


[*] the hack:

===
            def lvpo=this.editingContext().objectForGlobalID(gid) // finds it if exists in EC, or...
            if (!lvpo) {
                lvpo=ERXEOGlobalIDUtilities.fetchObjectWithGlobalID(this.editingContext(),gid) // ... fetches if does not
                println "???? fetched valid PO of ${this.permanentGlobalID()}: ${gid} -> ${lvpo} IN ${this.editingContext.hashCode()}"
            } else println "???? found valid PO of ${this.permanentGlobalID()}: ${gid} -> ${lvpo} IN ${this.editingContext.hashCode()}".toString()
===



 _______________________________________________
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:
    • Re: caching global IDs does not work as expected (followup: ordered and filtered fault efficiency)
      • From: OC <email@hidden>
References: 
 >ordered and filtered fault efficiency (From: OC <email@hidden>)
 >caching global IDs does not work as expected (followup: ordered and filtered fault efficiency) (From: OC <email@hidden>)
 >Re: caching global IDs does not work as expected (followup: ordered and filtered fault efficiency) (From: Chuck Hill <email@hidden>)
 >Re: caching global IDs does not work as expected (followup: ordered and filtered fault efficiency) (From: OC <email@hidden>)

  • Prev by Date: followup+workaround: saveChanges refaults relationships which target changed entities (was: way too many SELECTs?)
  • Next by Date: Re: ordered and filtered fault efficiency
  • Previous by thread: Re: caching global IDs does not work as expected (followup: ordered and filtered fault efficiency)
  • Next by thread: Re: caching global IDs does not work as expected (followup: ordered and filtered fault efficiency)
  • Index(es):
    • Date
    • Thread