Not quite so, localObject() will always return hollow object without any values inside it. When you read something out of it all data will be fetched from parent context so it will be there as expected. But when you try to set something ... well that's where all this problems come from.
On Tue, Jul 25, 2017 at 6:41 PM, Lon Varscsak <lon.varsc...@gmail.com> wrote: > Just to make sure we’re on the same page, when I local the object(s) into > an OC, all of the data and relationships are perfectly fine. It’s just > that once I access (by setting a property) one of the objects the reverse > relationships either get nulled out or I get that missing object > exception. It seems like the initial part is doing all the right stuff…but > something later is going awry. > > -Lon > > On Fri, Jul 21, 2017 at 2:06 AM, Nikita Timofeev <ntimof...@objectstyle.com> > wrote: > >> Well, I'm afraid that proper fix will be really difficult, as it'll >> need to deal with all possible cases how meaningful Pk/Fk and their >> combination can interact, while keeping in mind current behavior of >> unmapped Pk/Fk. >> If we narrow for now it down to only Pk, things can be slightly better >> (and may fit in scope of 4.1), as we can try to do proper >> synchronization of meaningful Pk set manually and ObjectId internal >> state, but still need to research this deeper. >> >> On Fri, Jul 21, 2017 at 4:10 AM, Lon Varscsak <lon.varsc...@gmail.com> >> wrote: >> > Okay, I’ve gotten farther, but still have an issue. I’ve removed the FK >> > IDs from my objects and if I don’t pre-assign PKs to them it’s all good. >> > But if I assign a PK as I go then I get: >> > >> > org.apache.cayenne.CayenneRuntimeException: [v.4.1.M1-SNAPSHOT Jul 19 >> 2017 >> > 19:49:41] Some parts of FK are missing in snapshot, relationship: Db >> > Relationship : toOne (billing_order_detail_sales.order_line_number, >> > order_detail_sales.order_line_number) >> > (billing_order_detail_sales.order_number, order_detail_sales.order_ >> number) >> > >> > at org.apache.cayenne.map.DbRelationship.targetPkSnapshotWithSrcSnapsho >> t( >> > DbRelationship.java:421) >> > >> > at org.apache.cayenne.DataRow.createTargetObjectId(DataRow.java:128) >> > >> > at org.apache.cayenne.access.DataRowUtils$2.visitToOne( >> DataRowUtils.java:184 >> > ) >> > >> > at org.apache.cayenne.reflect.generic.DataObjectToOneProperty.visit( >> > DataObjectToOneProperty.java:97) >> > >> > at org.apache.cayenne.reflect.PersistentDescriptor.visitProperties( >> > PersistentDescriptor.java:400) >> > >> > at org.apache.cayenne.reflect.LazyClassDescriptorDecorator. >> visitProperties( >> > LazyClassDescriptorDecorator.java:174) >> > >> > at org.apache.cayenne.access.DataRowUtils.forceMergeWithSnapshot( >> > DataRowUtils.java:136) >> > >> > at org.apache.cayenne.access.ObjectStore.registerDiff( >> ObjectStore.java:182) >> > >> > at org.apache.cayenne.access.ObjectStore.nodePropertyChanged( >> > ObjectStore.java:940) >> > >> > at >> > org.apache.cayenne.util.ObjectContextGraphAction. >> handleSimplePropertyChange( >> > ObjectContextGraphAction.java:102) >> > >> > at org.apache.cayenne.util.ObjectContextGraphAction. >> handlePropertyChange( >> > ObjectContextGraphAction.java:68) >> > >> > at org.apache.cayenne.BaseContext.propertyChanged(BaseContext.java:460) >> > >> > at org.apache.cayenne.CayenneDataObject.writeProperty( >> > CayenneDataObject.java:200) >> > >> > at >> > com.smarthealth.businesslogic.production.auto._BillingOrderDetailSales. >> setPersonalizationLineAmount( >> > _BillingOrderDetailSales.java:102) >> > >> > at >> > com.smarthealth.businesslogic.util.SHOrderController. >> calculatePersonalization( >> > SHOrderController.java:833) >> > >> > >> > So I’ve assigned one of the PKs (order_line_number), but order_number >> > doesn’t get assigned until the user clicks save. So this partial state >> > seems to confuse it too. I assume if I assign the order_number, then >> I’ll >> > get the previous error where it tries to fault from the DB. How >> difficult >> > would it be to modify Cayenne to deal with these TEMP objects better? >> > >> > >> > -Lon >> > >> > On Thu, Jul 20, 2017 at 10:58 AM, Lon Varscsak <lon.varsc...@gmail.com> >> > wrote: >> > >> >> Ah crap. :) I can’t really get rid of meaningful PKs (legacy system), >> but >> >> I can remove the PKs from the ObjEntity of the FK objects (Payments >> doesn’t >> >> need orderNumber and paymentNumber exposed). At that does seem to >> work. >> >> However, in Payments, I’d still need to assign the paymentNumber >> portion of >> >> the PK…what’s the best approach here (it’s not auto-assigned). >> >> >> >> Also, it seems like there could be a special case in this scenario when >> >> localing objects from another OC (parent) that handles TEMP ObjectIds >> >> differently. There would never be a situation where you’d want to go >> back >> >> to DB access for a TEMP object. >> >> >> >> Thanks! >> >> >> >> -Lon >> >> >> >> On Thu, Jul 20, 2017 at 1:28 AM, Nikita Timofeev < >> >> ntimof...@objectstyle.com> wrote: >> >> >> >>> Thanks for such a detailed example! >> >>> >> >>> Short version of what happening: meaningful FK drives Cayenne crazy. >> >>> It just can't handle this particular case, so easiest solution is to >> >>> get rid of those and everything will be ok. >> >>> >> >>> I've checked same case but without mapped FK and everything just >> >>> works, no relationships missing in parent or child context. >> >>> >> >>> A little bit more details why this happening: >> >>> >> >>> 1. NPE - is a result of missing value for mapped FK. from the Cayenne >> >>> POV FK is in snapshot came from parent context but it's null so >> >>> Cayenne should set relationship to null or otherwise there will be >> >>> problems when merging object with data from DB. This is what happening >> >>> in DataRowUtils. >> >>> 2. When you manually set orderNumber there is no NPE, but fault can't >> >>> be resolved because it is unknown by parent context where this object >> >>> has temp ObjectId and query goes to DB where no object exists (again, >> >>> this will not be the problem if Cayenne manages all your >> >>> relationships, it will solve temp ObjectId correctly) >> >>> >> >>> And there can be even more cases when meaningful Fk (as well as Pk) >> >>> can fail, so it is pretty general recommendation to stay away from >> >>> those as much as you can. >> >>> >> >>> On Thu, Jul 20, 2017 at 4:08 AM, Lon Varscsak <lon.varsc...@gmail.com> >> >>> wrote: >> >>> > Okay here’s a maven project that should work for you (it’s a wicket >> >>> > application, but that shouldn’t matter…I think all the dependencies >> >>> should >> >>> > work) . >> >>> > >> >>> > Here’s the file: >> >>> > https://www.dropbox.com/s/7mhq8zz5zfqthdv/cayennebug.tar.gz?dl=0 >> >>> > Use this url after running: http://localhost:8080/apps/cayennebug/ >> >>> > >> >>> > Here’s what’s happening. On the main page I create an Order object >> and >> >>> add >> >>> > 3 Payment objects to it. This is in the “parent” context and is just >> >>> in the >> >>> > context, not in the db. If you add a new Payment (link at bottom of >> the >> >>> > first page) everything works fine, the new Payment object is created >> in >> >>> the >> >>> > child (inside ChildPage.java) added to the “localed” Order. No >> >>> problems. >> >>> > You’ll get returned to the HomePage and you will see your new payment >> >>> added. >> >>> > >> >>> > If you EDIT one of the existing ones (1-3…maybe 4, but not sure) we >> >>> local >> >>> > the Order and the Payment (or grab the payment from the localed >> >>> Order…either >> >>> > way), then the moment you touch the Payment object (by changing the >> >>> amount) >> >>> > it clears it’s Order reverse relationship because it sees that the >> “id” >> >>> > isn’t set (which it isn’t yet, this would technically happen later on >> >>> save >> >>> > in my real world application). In this case you’ll get a NPE because >> >>> I’m >> >>> > logging out the Payment’s getOrder().something() and getOrder() is >> now >> >>> > returning null. You should be able to see that you’ll reach the >> line of >> >>> > code that I sent in my previous email (in DataRowUtils). >> >>> > >> >>> > So that leads to another problem. If I have a proper order number >> (you >> >>> can >> >>> > uncomment the line in HomePage.java), when you setAmount it will now >> >>> try to >> >>> > retrieve the object from the database which will obviously return no >> >>> results >> >>> > and throws the exception in my previous email (“Error resolving >> fault, >> >>> no >> >>> > matching row exists in the database for ObjectId”). >> >>> > >> >>> > This fails in 4.0.M5 and 4.1.M1-SNAPSHOT. Any help would be greatly >> >>> > appreciated. >> >>> > >> >>> > Thanks, >> >>> > >> >>> > Lon >> >>> > >> >>> > On Wed, Jul 19, 2017 at 1:24 PM, Lon Varscsak < >> lon.varsc...@gmail.com> >> >>> > wrote: >> >>> >> >> >>> >> I can also get it to throw this error: >> >>> >> >> >>> >> Caused by: org.apache.cayenne.FaultFailureException: >> >>> [v.4.1.M1-SNAPSHOT >> >>> >> Jul 19 2017 19:49:41] Error resolving fault, no matching row exists >> in >> >>> the >> >>> >> database for ObjectId: <ObjectId:OrderDetailSale, >> order_line_number=2, >> >>> >> order_number=55663878> >> >>> >> >> >>> >> at org.apache.cayenne.BaseContext.prepareForAccess(BaseContext. >> >>> java:365) >> >>> >> >> >>> >> at >> >>> >> org.apache.cayenne.CayenneDataObject.readProperty(CayenneDat >> >>> aObject.java:174) >> >>> >> >> >>> >> at >> >>> >> com.smarthealth.businesslogic.production.auto._OrderDetailSa >> >>> le.getPersonalizationDiscPercent(_OrderDetailSale.java:316) >> >>> >> >> >>> >> at >> >>> >> com.smarthealth.businesslogic.production.auto._OrderDetailSa >> >>> le.personalizationDiscPercent(_OrderDetailSale.java:319) >> >>> >> >> >>> >> at >> >>> >> com.smarthealth.businesslogic.production.BillingOrderDetailS >> >>> ales.personalizationDiscountAmount(BillingOrderDetailSales.java:26) >> >>> >> >> >>> >> at >> >>> >> com.smarthealth.businesslogic.production.BillingOrderDetailS >> >>> ales.extendedPrice(BillingOrderDetailSales.java:30) >> >>> >> >> >>> >> >> >>> >> Where the OrderDetailSale object in question is new on an >> OrderHeader >> >>> >> which isn’t new. >> >>> >> >> >>> >> -Lon >> >>> >> >> >>> >> On Wed, Jul 19, 2017 at 1:23 PM, Lon Varscsak < >> lon.varsc...@gmail.com> >> >>> >> wrote: >> >>> >>> >> >>> >>> Okay, I’ll see if I can work up a test case. Note: This only >> >>> happens if >> >>> >>> the objects in question are new objects (not in the db). When it >> >>> tries to >> >>> >>> find the “id” in DataRowUtils it comes back with nothing, so then >> it >> >>> nulls >> >>> >>> the reverse relationship out (even though at that point the reverse >> >>> >>> relationship is in the child and has all of it’s values). >> >>> >>> >> >>> >>> -Lon >> >>> >>> >> >>> >>> On Wed, Jul 19, 2017 at 12:34 AM, Nikita Timofeev >> >>> >>> <ntimof...@objectstyle.com> wrote: >> >>> >>>> >> >>> >>>> Hi Lon, >> >>> >>>> >> >>> >>>> I've tried to dig dipper into your case, and I can't repeat >> described >> >>> >>>> behavior, all I see is that toOne >> >>> >>>> relationship in object that moved to other context is faulted and >> >>> >>>> resolved on next access, >> >>> >>>> and no reverse relationships are affected. And that I assume is >> >>> >>>> expected behavior. >> >>> >>>> >> >>> >>>> And even more I can't figure out case when line 194 in >> DataRowUtils >> >>> can >> >>> >>>> be hit. >> >>> >>>> May be you can provide some simple test case? >> >>> >>>> >> >>> >>>> On Mon, Jul 17, 2017 at 9:14 PM, Lon Varscsak < >> >>> lon.varsc...@gmail.com> >> >>> >>>> wrote: >> >>> >>>> > Okay, that didn’t work. >> >>> >>>> > >> >>> >>>> > https://www.dropbox.com/s/68hsculni16ucg3/Screen%20Shot%2020 >> >>> 17-07-13%20at%2010.50.24%20AM.png?dl=0 >> >>> >>>> > >> >>> >>>> > -Lon >> >>> >>>> > >> >>> >>>> > On Mon, Jul 17, 2017 at 11:06 AM, Lon Varscsak >> >>> >>>> > <lon.varsc...@gmail.com> >> >>> >>>> > wrote: >> >>> >>>> > >> >>> >>>> >> Try this: >> >>> >>>> >> >> >>> >>>> >> http://gofile.me/34oeM/YdPU7U4j1 >> >>> >>>> >> >> >>> >>>> >> On Mon, Jul 17, 2017 at 10:08 AM, Andrus Adamchik >> >>> >>>> >> <and...@objectstyle.org> >> >>> >>>> >> wrote: >> >>> >>>> >> >> >>> >>>> >>> Unfortunately the mailing list strips attachments. Could you >> post >> >>> >>>> >>> the >> >>> >>>> >>> image elsewhere, like GoogleDrive or Dropbox? >> >>> >>>> >>> >> >>> >>>> >>> Andrus >> >>> >>>> >>> >> >>> >>>> >>> > On Jul 13, 2017, at 8:51 PM, Lon Varscsak < >> >>> lon.varsc...@gmail.com> >> >>> >>>> >>> wrote: >> >>> >>>> >>> > >> >>> >>>> >>> > I found the line that’s nulling it out…I just don’t >> understand >> >>> at >> >>> >>>> >>> > this >> >>> >>>> >>> deep level what’s going on. Here’s the strack trace: >> >>> >>>> >>> > >> >>> >>>> >>> > On Thu, Jul 13, 2017 at 10:43 AM, Lon Varscsak >> >>> >>>> >>> > <lon.varsc...@gmail.com> >> >>> >>>> >>> wrote: >> >>> >>>> >>> > I have an object (that’s new) in ObjectContextA that has a >> >>> >>>> >>> > relationship >> >>> >>>> >>> to another new object (same OC) which also has a reverse >> >>> >>>> >>> relationship. I >> >>> >>>> >>> then create a child of that OC (ObjectContactB) and grab a >> local >> >>> >>>> >>> version of >> >>> >>>> >>> the first object. At that time, the relationship object (and >> >>> it’s >> >>> >>>> >>> reverse) >> >>> >>>> >>> is there and all is good in the world. >> >>> >>>> >>> > >> >>> >>>> >>> > The moment I touch the object (setting a simple property >> with >> >>> >>>> >>> writeProperty) in the relationship the reverse relationship >> gets >> >>> >>>> >>> nulled >> >>> >>>> >>> out. Any thoughts as to why this might happen? >> >>> >>>> >>> > >> >>> >>>> >>> > -Lon >> >>> >>>> >>> > >> >>> >>>> >>> >> >>> >>>> >>> >> >>> >>>> >> >> >>> >>>> >> >>> >>>> >> >>> >>>> >> >>> >>>> -- >> >>> >>>> Best regards, >> >>> >>>> Nikita Timofeev >> >>> >>> >> >>> >>> >> >>> >> >> >>> > >> >>> >> >>> >> >>> >> >>> -- >> >>> Best regards, >> >>> Nikita Timofeev >> >>> >> >> >> >> >> >> >> >> -- >> Best regards, >> Nikita Timofeev >> -- Best regards, Nikita Timofeev