Hi Roger,
The error attached says:
primary key dictionary {oidProductItem = 91; oidPayment = 241; }
Which seems to indicate the ProductItemPayment is modeled with a compound PK,
however the model attached indicates the OID is the PK on that table. Those two
things seem to be contradicting each other.
I will hazard a guess that the flattened relationship toProductItems is causing
the issue. Unless that relationship is needed for some to-many qualifier, then
it may be easiest to simply remove it and create a cover method that returns
the result of traversing that relationship on the entity class. Something like…
//Totally untested suggestion :-)
public NSArray<ProductItem> toProductItems() {
return
(NSArray<ProductItem>)toProductItemPayments().valueForKeyPath(“toProductItem.@flatten”);
}
Assuming that removing the relation solves the issue.
On Jul 21, 2015, at 11:07 AM, Roger Perryman <[email protected]> wrote:
> Thanks Samuel. The interesting thing is that I do not have a relationship
> ProductItemPayment.toProductItems (with an s) in my model. I tried to reduce
> the image that the moderators blocked but it became unreadable so here is the
> textual form. ProductItemPayments is a custom class with additional
> attributes and relationships and a single primary key (I try to avoid
> compound keys except for EOGenericRecord entities).
>
> § PK » To-Many
> ƒ FK › To-One
> ø Allows Null ø Allows Null
> ◊ Class Property ¬ Locking Attribute
> ≈ Flattened Relationship
>
> ProductItem
> -----------
> § ¬ oid
> ◊ ¬ version
> ---------
> ◊ unitAmount
> ◊ unitQuantity
> ƒ ø oidInvoice
> ƒ oidProduct
> -----------
> › ◊ toProduct oidProduct -> Product.oid
> › ◊ ø toInvoice oidInvoice -> Invoice.oid
> » ◊ ø toProductItemPayments oid <- ProductItemPayment.oidProductItem
> » ◊ ≈ ø toPayments toProductItemPayments.toPayment
>
>
> ProductItemPayment
> ------------------
> § ¬ oid
> ◊ ¬ version
> ---------
> ◊ amountPledged
> ƒ ø oidPayment
> ƒ oidProductItem
> -----------
> › ◊ ø toProductItem oidProductItem -> ProductItem.oid
> › ◊ ø toPayment oidPayment -> Payment.oid
> » ◊ ø toInvoiceAudits oid <- InvoiceAudit.oidProductItem
>
>
> Payment
> -------
> § ¬ oid
> ◊ ¬ version
> ---------
> ◊ unitAmount
> -----------
> » ◊ ≈ ø toProductItems toProductItemPayments.toProductItem
> » ◊ ø toProductItemPayments oid <- ProductItemPayment.oidProductItem
>
>
>> On Jul 20, 2015, at 8:49 PM, Samuel Pelletier <[email protected]> wrote:
>>
>> Hi Roger,
>>
>> There is something strange, I may misunderstand the error but it seems the
>> toProductItems relationship of ProductItemPayment specify a join on the
>> oidProductItem and oidPayment columns but all your entities seems to have
>> single column primary keys,
>>
>> I suggest to check your relationship definitions to make sure they use the
>> corrects columns, starting with the toProductItems in ProductItemPayment.
>>
>> Samuel
>>
>>> Le 2015-07-20 à 15:39, Roger Perryman <[email protected]> a écrit :
>>>
>>> I sent this over the weekend but I didn’t notice that it was held pending
>>> approval from the list moderator. I didn’t realize there was a moderator.
>>> Apparently the message was too big due to the image I had attached showing
>>> the relevant parts of the model.
>>>
>>> I’ve done some code changes and now everything lives in the same EC. But
>>> now saveChanges() is blowing up
>>>
>>> WARN 07/19 21:28:55 (ERXNSLogLog4jBridge.java:44) -
>>> <er.extensions.appserver.ERXComponentRequestHandler>: Exception occurred
>>> while handling request:
>>> java.lang.IllegalStateException: A valid global ID could not be obtained
>>> for entity named ProductItemPayment, relationship named toProductItems,
>>> primary key dictionary {oidProductItem = 91; oidPayment = 241; }.
>>> [2015-7-19 21:28:55 EDT] <WorkerThread6> java.lang.IllegalStateException: A
>>> valid global ID could not be obtained for entity named ProductItemPayment,
>>> relationship named toProductItems, primary key dictionary {oidProductItem =
>>> 91; oidPayment = 241; }.
>>> at
>>> com.webobjects.eoaccess.EODatabaseContext.databaseOperationForIntermediateRowFromSourceObject(EODatabaseContext.java:4871)
>>> at
>>> com.webobjects.eoaccess.EODatabaseContext.recordInsertForIntermediateRowFromSourceObject(EODatabaseContext.java:4888)
>>> at
>>> com.webobjects.eoaccess.EODatabaseContext.relayAttributesInRelationshipSourceObjectDestinationObject(EODatabaseContext.java:4913)
>>> at
>>> com.webobjects.eoaccess.EODatabaseContext.relayAttributesInRelationshipSourceObjectDestinationObjects(EODatabaseContext.java:4966)
>>> at
>>> com.webobjects.eoaccess.EODatabaseContext.recordChangesInEditingContext(EODatabaseContext.java:6036)
>>> at
>>> com.webobjects.eocontrol.EOObjectStoreCoordinator.saveChangesInEditingContext(EOObjectStoreCoordinator.java:373)
>>> at
>>> com.webobjects.eocontrol.EOEditingContext.saveChanges(EOEditingContext.java:3192)
>>> at er.extensions.eof.ERXEC._saveChanges(ERXEC.java:1179)
>>> at er.extensions.eof.ERXEC.saveChanges(ERXEC.java:1102)
>>> at
>>> com.xeotech.mdspas.components.AdHocStorePayment.savePayment(AdHocStorePayment.java:255)
>>>
>>> All of the objects are in the EC
>>>
>>> EditingContext: ERXEC@12aa5705
>>> Registered [395]: List omitted
>>> Inserted [ 8]: [Invoice PK: 267], [InvoiceAudit PK: 66],
>>> [Payment PK: 241], [PaymentDetail PK: 237],
>>> [ProductItem PK: 91], [ProductItemPayment PK:
>>> 77], [ShoppingCart PK: 55],
>>> [ShoppingCartProduct PK: 54]
>>> Updated [ 3]: <Account pk:167>, <Practice pk:1>, <User pk:2>
>>>
>>> and they are assigned as I would expect
>>>
>>> Payment(6f44eaf7) :
>>> globalID = <Payment PK: 241> { pending }
>>> editingContext = ERXEC@12aa5705 Added
>>> to EC, Updated in EC
>>>
>>> Attributes
>>> comments = NULL
>>> dateRecordCreated = Sunday July 19, 2015 @ 09:25 PM *
>>> dateRecordModified = Sunday July 19, 2015 @ 09:25 PM *
>>> isActive = true *
>>> paymentNumber = FPA20150719212521850 *
>>> totalAmount = 107.0
>>> transactionDate = Sunday July 19, 2015 @ 09:25 PM
>>> version = 1 *
>>>
>>> To-One Relationships
>>> toAccount = <Account PK: 167>
>>> toAppointment = NULL
>>> toCashier = <User PK: 2> ( Patrick Abuzeni )
>>> *
>>> toRequestType = <RequestType PK: 1> ( One Time )
>>> *
>>> toTransactionType = NULL
>>>
>>> To-Many Relationships
>>>
>>> toPaymentDetails [ 1 ]
>>> 1) eoObj = <PaymentDetail PK: 237> ( CAC201507190BFB ) {
>>> pending }
>>>
>>> toProductItemPayments [ 1 ]
>>> 1) eoObj = <ProductItemPayment PK: 77> { pending }
>>>
>>> toProductItems [ 1 ]
>>> 1) eoObj = <ProductItem PK: 91> { pending }
>>>
>>>
>>>
>>> ProductItem(d63d22) :
>>> globalID = <ProductItem PK: 91> { pending }
>>> editingContext = ERXEC@12aa5705 Added
>>> to EC, Updated in EC
>>>
>>> Attributes
>>> dateRecordCreated = Sunday July 19, 2015 @ 09:24 PM *
>>> dateRecordModified = Sunday July 19, 2015 @ 09:24 PM *
>>> discountAmount = 0.0 *
>>> isActive = true *
>>> unitAmount = 100.0 *
>>> unitQuantity = 1 *
>>> version = 1 *
>>>
>>> To-One Relationships
>>> toAuthorizedBy = NULL
>>> toInvoice = <Invoice PK: 267> { pending }
>>> toProduct = <Product PK: 3> ( Abdominoplasty
>>> Garment ) *
>>>
>>> To-Many Relationships
>>>
>>> toPayments [ 1 ]
>>> 1) eoObj = <Payment PK: 241> { pending }
>>>
>>> toProductItemPayments [ 1 ]
>>> 1) eoObj = <ProductItemPayment PK: 77> { pending }
>>>
>>> toShoppingCartProducts [ 1 ]
>>> 1) eoObj = <ShoppingCartProduct PK: 54> { pending }
>>>
>>>
>>>
>>> ProductItemPayment(42d9e298) :
>>> globalID = <ProductItemPayment PK: 77> {
>>> pending }
>>> editingContext = ERXEC@12aa5705 Added
>>> to EC, Updated in EC
>>>
>>> Attributes
>>> amountPledged = 107.0 *
>>> datePaid = Sunday July 19, 2015 @ 09:25 PM *
>>> dateRecordCreated = Sunday July 19, 2015 @ 09:25 PM *
>>> dateRecordModified = Sunday July 19, 2015 @ 09:25 PM *
>>> isActive = true *
>>> version = 1 *
>>>
>>> To-One Relationships
>>> toPayment = <Payment PK: 241> { pending }
>>> toProductItem = <ProductItem PK: 91> { pending } *
>>>
>>> To-Many Relationships
>>>
>>> toInvoiceAudits [ 1 ]
>>> 1) eoObj = <InvoiceAudit PK: 66> { pending }
>>>
>>> Diagram of the relevant parts of the model available upon request.
>>>
>>>
>>> Any thoughts would be welcome.
>>>
>>> Roger
>>>
>>>
>>>> On Jul 16, 2015, at 4:41 PM, Roger Perryman <[email protected]> wrote:
>>>>
>>>> Thanks Aaron and Chuck for your replies. I was fairly sure (afraid?) what
>>>> the answers would be. I was hoping their might be some WOnderful magical
>>>> method that could be used to “pull" the objects over since that is what it
>>>> looked like EOF did. I’ll check out ERXCopyable and see if that helps. I’m
>>>> also looking at restructuring the code to remove the need for the extra EC
>>>> and using a child EC as a backup plan.
>>>>
>>>> A few years ago when I first noticed that localInstanceOfObject returned
>>>> NULL for new objects I thought it must be a bug. As I mentioned, my “fix”
>>>> of just returning the original object seemed to work and I never thought
>>>> much more about. It seemed to do “the right thing." I can only assume that
>>>> it never encountered a toMany relationship that was new (that is the only
>>>> real difference here) and the other EC was never saved so EOF didn’t
>>>> notice that danger lurked. I will need to take a closer look and make sure
>>>> to correct any code that needs it.
>>>>
>>>> Roger
>>>>
>>>>
>>>>> On Jul 16, 2015, at 2:20 PM, Chuck Hill <[email protected]> wrote:
>>>>>
>>>>> An EO lives in a specific EC and can’t be moved between then as a single
>>>>> Java object instances. The reason why localInstnace won’t work for new
>>>>> objects is that it does not move or copy the EO into the new EC. It
>>>>> creates and brand new Java EO object and loads its values from the
>>>>> snapshot cache (or possibly from the database but let’s not over
>>>>> complicate this explanation). An unsaved EO has no values in the
>>>>> snapshot cache (they get added when saved), so it is flat out not
>>>>> possible to localnstance a new object without some major changes to EOF.
>>>>>
>>>>> What might work for you is a child EC. You can then revert what changes
>>>>> you don’t want and save into the parent EC for final saving.
>>>>>
>>>>> ERXCopyable might also be a solution.
>>>>>
>>>>> Chuck
>>>>>
>>>>> From: <[email protected]> on
>>>>> behalf of Aaron Rosenzweig <[email protected]>
>>>>> Date: Thursday, July 16, 2015 at 10:56 AM
>>>>> To: Roger Perryman <[email protected]>
>>>>> Cc: WebObjects Dev List <[email protected]>
>>>>> Subject: Re: localInstanceOfObject
>>>>>
>>>>> Hi Roger,
>>>>>
>>>>> I skimmed your post.
>>>>>
>>>>> You cannot local instance an unsaved object. You just cannot do it. Don’t
>>>>> try anything clever… the EO is tied to a unit of work (editing context)
>>>>> and without ever being saved it simply is not possible to local instance
>>>>> it.
>>>>>
>>>>> You may have to use the “memento” pattern for your particular case. Make
>>>>> a simple java object, nothing about DB persistence… and then make it an
>>>>> EO only after it has passed muster.
>>>>> AARON ROSENZWEIG / Chat 'n Bike
>>>>> e: [email protected] t: (301) 956-2319
>>>>>
>>>>>
>>>>> On Jul 16, 2015, at 1:04 PM, Roger Perryman <[email protected]> wrote:
>>>>>
>>>>>> Hi All!
>>>>>>
>>>>>> I am having an issue with local instancing an EO and I would like some
>>>>>> help understanding the problem. I found an old thread started by Kieran
>>>>>> Kelleher where he was having similar issues. Mike Schrag had mentioned
>>>>>> that EOF couldn't tell if a new object localInstanced from another EC
>>>>>> had later been saved in the other EC which could result in collisions so
>>>>>> it erred on the side of caution. So I am probably using the method
>>>>>> inappropriately. Hopefully someone will point out the problem and offer
>>>>>> the correct way.
>>>>>>
>>>>>> I've noticed that when I localInstance a new EO (not yet saved to the
>>>>>> database) both the WebObjects and WOnder versions return null for the
>>>>>> EO. It seems odd for the method to return null if it is a new method. I
>>>>>> wrote a customized version that detects if it is a new EO and just
>>>>>> returns the original EO. I've been using it for quite some time now and
>>>>>> it at least _seemed_ to work better. My use cases must have avoided
>>>>>> conflicts.
>>>>>>
>>>>>> However, I've recently noticed problems. They may have been there
>>>>>> before. I did recently update my computer (OSX 10.10.3) and dev
>>>>>> environment to the latest WOnder (6.1.4-SNAPSHOT), Java 8 (1.8.0_45),
>>>>>> Eclipse (4.4.2) with matching WOLips.
>>>>>>
>>>>>> I'm creating a new EC because many of the objects in the original EC are
>>>>>> disposable and are not intended to be written to the DB, even if they
>>>>>> happen to change. The problem is because of passing the original EO to
>>>>>> the new EC instead of NULL that would normally be returned but the
>>>>>> relationships cannot be NULL. I wrote a clone method for some of the
>>>>>> objects for testing but it got very complex very fast because of deeper
>>>>>> objects in the relationship. As you can see from my debugging output,
>>>>>> all required fields (*'s) are set and relationships are set.
>>>>>>
>>>>>> This group is the objects in the old (original) EC and the original
>>>>>> Invoice that has not been saved yet but it has had an oid assigned. It
>>>>>> also has a to-many relationship to new ProductItem objects.
>>>>>>
>>>>>> OLD EC
>>>>>> EditingContext:ERXEC@2d334040
>>>>>> Registered [375]:List omitted
>>>>>> Inserted [ 5]:[Invoice PK: 250], [ProductItem PK: 74],
>>>>>> [ProductItemPayment PK: 61],
>>>>>> [ShoppingCart PK: 44], [ShoppingCartProduct PK: 44]
>>>>>> Updated [ 3]:<Account pk:167>, <Practice pk:1>, <User pk:2>
>>>>>> Deleted [ 0]:EMPTY
>>>>>>
>>>>>> OLD Invoice:
>>>>>> Invoice(5bdf1c53) :
>>>>>> globalID = <Invoice PK: 250> { pending }
>>>>>> editingContext = ERXEC@2d334040 Added to EC
>>>>>>
>>>>>> Attributes
>>>>>> approvedDeposit = NULL
>>>>>> dateRecordCreated = Wednesday July 15, 2015 @ 03:19 PM
>>>>>> *
>>>>>> dateRecordModified = Wednesday July 15, 2015 @ 03:19 PM
>>>>>> *
>>>>>> invoiceDate = Wednesday July 15, 2015 @ 03:19 PM
>>>>>> *
>>>>>> invoiceDiscount = NULL
>>>>>> invoiceNumber = IJD20150715151938381 *
>>>>>> isActive = true *
>>>>>> taxRate = 0.07 *
>>>>>> totalFees = 0.0 *
>>>>>> totalNonTaxable = 0.0 *
>>>>>> totalTaxable = 0.0 *
>>>>>> version = 1 *
>>>>>>
>>>>>> To-One Relationships
>>>>>> toAccount = <Account PK: 167> *
>>>>>> toCheckListPostOp = NULL
>>>>>> toCheckListPreOp = NULL
>>>>>> toCheckListSurgery = NULL
>>>>>> toCoordinator = <User PK: 2> ( Jane Doe ) *
>>>>>> toInvoiceStatus = <InvoiceStatus PK: 1> ( Open ) *
>>>>>> toInvoiceType = <InvoiceType PK: 2> ( Invoice ) *
>>>>>> toPractice = <Practice PK: 1> (
>>>>>> DEFAULT_PRACTICE ) *
>>>>>> toSurgeryRequest = NULL
>>>>>>
>>>>>> To-Many Relationships
>>>>>>
>>>>>> toProductItems[ 1 ]
>>>>>> 1) eoObj = <ProductItem PK: 74> { pending }
>>>>>>
>>>>>> toRequestDetails
>>>>>> No Records
>>>>>>
>>>>>> toServiceItems
>>>>>> No Records
>>>>>>
>>>>>>
>>>>>> This group is the objects in the new EC and the cloned Invoice that has
>>>>>> not been saved yet but it has had an oid assigned. It also has a to-many
>>>>>> relationship to new ProductItem objects. Note the oid has increased and
>>>>>> unique attributes have been adjusted. When I try to save, it fails
>>>>>> because the objects associated with ProductItems have a relationship in
>>>>>> a different EC (and retain their original oids).
>>>>>>
>>>>>> NEW Invoice:
>>>>>> Invoice(6371d408) :
>>>>>> globalID = <Invoice PK: 251> { pending }
>>>>>> editingContext = ERXEC@1c741963 Added to EC,
>>>>>> Updated in EC
>>>>>>
>>>>>> Attributes
>>>>>> approvedDeposit = NULL
>>>>>> dateRecordCreated = Wednesday July 15, 2015 @ 03:30 PM
>>>>>> *
>>>>>> dateRecordModified = Wednesday July 15, 2015 @ 03:30 PM
>>>>>> *
>>>>>> invoiceDate = Wednesday July 15, 2015 @ 03:19 PM
>>>>>> *
>>>>>> invoiceDiscount = NULL
>>>>>> invoiceNumber = IJD20150715151938952 *
>>>>>> isActive = true *
>>>>>> taxRate = 0.07 *
>>>>>> totalFees = 0.0 *
>>>>>> totalNonTaxable = 0.0 *
>>>>>> totalTaxable = 0.0 *
>>>>>> version = 1 *
>>>>>>
>>>>>> To-One Relationships
>>>>>> toAccount = <Account PK: 167> *
>>>>>> toCheckListPostOp = NULL
>>>>>> toCheckListPreOp = NULL
>>>>>> toCheckListSurgery = NULL
>>>>>> toCoordinator = <User PK: 2> ( Jane Doe ) *
>>>>>> toInvoiceStatus = <InvoiceStatus PK: 1> ( Open ) *
>>>>>> toInvoiceType = <InvoiceType PK: 2> ( Invoice ) *
>>>>>> toPractice = <Practice PK: 1> (
>>>>>> DEFAULT_PRACTICE ) *
>>>>>> toSurgeryRequest = NULL
>>>>>>
>>>>>> To-Many Relationships
>>>>>>
>>>>>> toProductItems[ 1 ]
>>>>>> 1) eoObj = <ProductItem PK: 74> { pending }
>>>>>>
>>>>>> toRequestDetails
>>>>>> No Records
>>>>>>
>>>>>> toServiceItems
>>>>>> No Records
>>>>>>
>>>>>> NEW ProductItems:
>>>>>> (
>>>>>> ProductItem(1695d9bc) :
>>>>>> globalID = <ProductItem PK: 74> { pending }
>>>>>> editingContext = ERXEC@2d334040 Added to EC,
>>>>>> Updated in EC
>>>>>>
>>>>>> Attributes
>>>>>> dateRecordCreated = Wednesday July 15, 2015 @ 03:15 PM
>>>>>> *
>>>>>> dateRecordModified = Wednesday July 15, 2015 @ 03:15 PM
>>>>>> *
>>>>>> discountAmount = 0.0 *
>>>>>> isActive = true *
>>>>>> unitAmount = 100.0 *
>>>>>> unitQuantity = 1 *
>>>>>> version = 1 *
>>>>>>
>>>>>> To-One Relationships
>>>>>> toAuthorizedBy = NULL
>>>>>> toInvoice = <Invoice PK: 250> { pending }
>>>>>> toProduct = <Product PK: 3> ( Abdominoplasty
>>>>>> Garment ) *
>>>>>>
>>>>>> To-Many Relationships
>>>>>>
>>>>>> toGiftCards
>>>>>> No Records
>>>>>>
>>>>>> toPayments
>>>>>> No Records
>>>>>>
>>>>>> toProductItemPayments[ 1 ]
>>>>>> 1) eoObj = <ProductItemPayment PK: 61> { pending }
>>>>>>
>>>>>> toShoppingCartProducts[ 1 ]
>>>>>> 1) eoObj = <ShoppingCartProduct PK: 44> { pending }
>>>>>> )
>>>>>>
>>>>>> NEW EC
>>>>>> EditingContext:ERXEC@1c741963
>>>>>> Registered [179]:List omitted
>>>>>> Inserted [ 1]:[Invoice PK: 251]
>>>>>> Updated [ 3]:<Account pk:167>, <Practice pk:1>, <User pk:2>
>>>>>> Deleted [ 0]:EMPTY
>>>>>>
>>>>>>
>>>>>> Is there a correct way to "localInstance" an unsaved EO? Or do I need to
>>>>>> restructure the code and perhaps use nested ECs?
>>>>>>
>>>>>> Thanks,
>>>>>>
>>>>>> Roger
>>>>>>
>>>>>> _______________________________________________
>>>>>> Do not post admin requests to the list. They will be ignored.
>>>>>> Webobjects-dev mailing list ([email protected])
>>>>>> Help/Unsubscribe/Update your Subscription:
>>>>>> https://lists.apple.com/mailman/options/webobjects-dev/aaron%40chatnbike.com
>>>>>>
>>>>>> This email sent to [email protected]
>>>>>
>>>>
>>>> _______________________________________________
>>>> Do not post admin requests to the list. They will be ignored.
>>>> Webobjects-dev mailing list ([email protected])
>>>> Help/Unsubscribe/Update your Subscription:
>>>> https://lists.apple.com/mailman/options/webobjects-dev/roger%40xeotech.com
>>>>
>>>> This email sent to [email protected]
>>>
>>>
>>> _______________________________________________
>>> Do not post admin requests to the list. They will be ignored.
>>> Webobjects-dev mailing list ([email protected])
>>> Help/Unsubscribe/Update your Subscription:
>>> https://lists.apple.com/mailman/options/webobjects-dev/samuel%40samkar.com
>>>
>>> This email sent to [email protected]
>
> _______________________________________________
> Do not post admin requests to the list. They will be ignored.
> Webobjects-dev mailing list ([email protected])
> Help/Unsubscribe/Update your Subscription:
> https://lists.apple.com/mailman/options/webobjects-dev/rgurley%40smarthealth.com
>
> This email sent to [email protected]
_______________________________________________
Do not post admin requests to the list. They will be ignored.
Webobjects-dev mailing list ([email protected])
Help/Unsubscribe/Update your Subscription:
https://lists.apple.com/mailman/options/webobjects-dev/archive%40mail-archive.com
This email sent to [email protected]