cayenne-user mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Nikita Timofeev <ntimof...@objectstyle.com>
Subject Re: Exception when adding a new object to two different relationships
Date Fri, 08 Sep 2017 14:46:47 GMT
It's circular relationships with PKs generated by DB. This case Cayenne
can't handle, as IDs become available only after insert and insert is
impossible without these values as they are used for FKs.
IIRC there was a discussion about this case somewhere, and solution will be
really hard, something like insert first data without FK then update only
FKs.
Workaround is to split creation of objects and their linkage (you can wrap
this in transaction to have atomicity).

On Fri, Sep 8, 2017 at 5:30 PM, Hugi Thordarson <hugi@karlmenn.is> wrote:

> Hi Amadeo,
> thanks for the pointer. No, the reverse relationship doesn't matter (and
> removing it doesn't help). I have now removed it in the github repo.
>
> And this is reproducible in different projects, I just created this smalll
> project to serve as an isolated runnable example.
>
> - hugi
>
>
> > On 8 Sep 2017, at 14:20, Amedeo Mantica <amedeomantica@me.com> wrote:
> >
> > I see an untitledRel in the Model, it looks like to be a stub inverse
> relationship... have you tried to remove it ?
> >
> > Amedeo
> >
> >> On 8 Sep 2017, at 14:05, Hugi Thordarson <hugi@karlmenn.is> wrote:
> >>
> >> Hi all,
> >> I'm encountering what I believe to be a bug, that someone more familiar
> with Cayenne's internals than me might want to take a look at :)
> >>
> >> In short: If I create a new DataObject, add it to two different
> relationships on another object and then attempt to commit the whole
> thing—it fails.
> >>
> >> Consider the following code:
> >>
> >> ObjectContext oc = createContext();
> >> Person person = oc.newObject( Person.class );
> >> Address address = oc.newObject( Address.class );
> >> person.addToAddresses( address );
> >> person.setLatestAddress( address );
> >>
> >> oc.commitChanges();
> >>
> >> This will result in the following exception:
> >>
> >> Exception in thread "main" org.apache.cayenne.CayenneRuntimeException:
> [v.4.1.M1-SNAPSHOT Aug 31 2017 12:03:09] Can't extract a master key.
> Missing key (id), master ID (<ObjectId:Person, TEMP:00000058A5520119>)
> >>      at org.apache.cayenne.access.DataDomainSyncBucket$
> PropagatedValueFactory.get(DataDomainSyncBucket.java:290)
> >>      at org.apache.cayenne.query.BatchQueryRow.getValue(
> BatchQueryRow.java:64)
> >>      at org.apache.cayenne.query.InsertBatchQuery$1.getValue(
> InsertBatchQuery.java:63)
> >>      at org.apache.cayenne.access.translator.batch.
> InsertBatchTranslator.doUpdateBindings(InsertBatchTranslator.java:121)
> >>      at org.apache.cayenne.access.translator.batch.
> DefaultBatchTranslator.updateBindings(DefaultBatchTranslator.java:78)
> >>      at org.apache.cayenne.access.jdbc.BatchAction.
> runAsIndividualQueries(BatchAction.java:163)
> >>      at org.apache.cayenne.access.jdbc.BatchAction.
> performAction(BatchAction.java:87)
> >>      at org.apache.cayenne.access.DataNodeQueryAction.runQuery(
> DataNodeQueryAction.java:97)
> >>      at org.apache.cayenne.access.DataNode.performQueries(
> DataNode.java:293)
> >>      at org.apache.cayenne.access.DataDomainFlushAction.runQueries(
> DataDomainFlushAction.java:233)
> >>      at org.apache.cayenne.access.DataDomainFlushAction.flush(
> DataDomainFlushAction.java:153)
> >>      at org.apache.cayenne.access.DataDomain.onSyncFlush(
> DataDomain.java:633)
> >>      at org.apache.cayenne.access.DataDomain.onSyncNoFilters(
> DataDomain.java:603)
> >>      at org.apache.cayenne.access.DataDomain$DataDomainSyncFilterChain.
> onSync(DataDomain.java:764)
> >>      at org.apache.cayenne.tx.TransactionFilter$1.perform(
> TransactionFilter.java:73)
> >>      at org.apache.cayenne.tx.TransactionFilter$1.perform(
> TransactionFilter.java:70)
> >>      at org.apache.cayenne.tx.DefaultTransactionManager.
> performInTransaction(DefaultTransactionManager.java:87)
> >>      at org.apache.cayenne.tx.DefaultTransactionManager.
> performInLocalTransaction(DefaultTransactionManager.java:59)
> >>      at org.apache.cayenne.tx.DefaultTransactionManager.
> performInTransaction(DefaultTransactionManager.java:52)
> >>      at org.apache.cayenne.tx.DefaultTransactionManager.
> performInTransaction(DefaultTransactionManager.java:40)
> >>      at org.apache.cayenne.tx.TransactionFilter.onSync(
> TransactionFilter.java:70)
> >>      at org.apache.cayenne.access.DataDomain$DataDomainSyncFilterChain.
> onSync(DataDomain.java:764)
> >>      at org.apache.cayenne.access.DataDomain.onSync(DataDomain.
> java:590)
> >>      at org.apache.cayenne.access.DataContext.flushToParent(
> DataContext.java:742)
> >>      at org.apache.cayenne.access.DataContext.commitChanges(
> DataContext.java:691)
> >>      at pktest.Main.main(Main.java:28)
> >>
> >>
> >>
> >> If someone would like to have a look, I've created a project that
> replicates the problem—just build it and run pktest.Main
> >>
> >> https://github.com/hugith/pktest <https://github.com/hugith/pktest>
> >>
> >> Cheers,
> >> - hugi
> >
>
>


-- 
Best regards,
Nikita Timofeev

Mime
  • Unnamed multipart/alternative (inline, None, 0 bytes)
View raw message