You are viewing a plain text version of this content. The canonical link for it is here.
Posted to user@cayenne.apache.org by Lon Varscsak <lo...@gmail.com> on 2021/11/16 23:06:58 UTC

Problem with optional to-one deletion

Hey all,

I have a setup where I have an optional to-one relationship, but when I try
to clear the relationship and commitChanges, I get a low-level Cayenne
error along with some in appropriate sql generated.

where it's doing an UPDATE to order_detail_costs should be a no-op, because
the object was removed from it's parent (order_detail_sales) with
setOrderDetailCost(null) along with a
objectContext.deleteObject(orderDetailCost).  This is probably a problem
for Nikita to look at, but I figured someone else may have run into this as
well.  It's unusual for me to have optional to-one relationships, but it
does happen.

Here is a sample project (Debug As -> Java Application) to try (link to my
Synology):
https://varscsak.synology.me:5001/d/s/mI7SBS6fApoUMNT1K5lfpaCXHKEkHkgd/jIy5Ug64Hjp2ieZzOceknc39sjBasJLE-T74gPgqKEgk

...snip...

Nov 16 15:27:55 INFO  org.apache.cayenne.log.JdbcEventLogger  - INSERT INTO
"order_header"( "attribute_1", "attribute_2", "order_number") VALUES( ?, ?,
?)

Nov 16 15:27:55 INFO  org.apache.cayenne.log.JdbcEventLogger  - [bind:
1->attribute_1:'TEST1', 2->attribute_2:1, 3->order_number:1]

Nov 16 15:27:55 INFO  org.apache.cayenne.log.JdbcEventLogger  - === updated
1 row.

Nov 16 15:27:55 INFO  org.apache.cayenne.log.JdbcEventLogger  - INSERT INTO
"order_detail_sales"( "detail_attr_1", "detail_attr_2",
"order_line_number", "order_number") VALUES( ?, ?, ?, ?)

Nov 16 15:27:55 INFO  org.apache.cayenne.log.JdbcEventLogger  - [bind:
1->detail_attr_1:'TEST1', 2->detail_attr_2:1, 3->order_line_number:1,
4->order_number:1]

Nov 16 15:27:55 INFO  org.apache.cayenne.log.JdbcEventLogger  - === updated
1 row.

Nov 16 15:27:55 INFO  org.apache.cayenne.log.JdbcEventLogger  - UPDATE
"order_detail_costs" SET "order_number" = ?, "order_line_number" = ? WHERE
( "order_line_number" = ? ) AND ( "order_number" = ? )

Nov 16 15:27:55 INFO  org.apache.cayenne.log.JdbcEventLogger  - *** error.

java.lang.UnsupportedOperationException

at java.util.Collections$UnmodifiableMap.put(Collections.java:1459)

at org.apache.cayenne.query.BatchQueryRow.getValue(BatchQueryRow.java:80)

at org.apache.cayenne.query.UpdateBatchQuery$1.getValue(
UpdateBatchQuery.java:124)

at
org.apache.cayenne.access.translator.batch.UpdateBatchTranslator.updateBindings(
UpdateBatchTranslator.java:80)

at org.apache.cayenne.access.jdbc.BatchAction.runAsIndividualQueries(
BatchAction.java:191)

at org.apache.cayenne.access.jdbc.BatchAction.performAction(
BatchAction.java:93)

at org.apache.cayenne.access.DataNodeQueryAction.runQuery(
DataNodeQueryAction.java:97)

at org.apache.cayenne.access.DataNode.performQueries(DataNode.java:273)

at
org.apache.cayenne.access.flush.DefaultDataDomainFlushAction.lambda$executeQueries$6(
DefaultDataDomainFlushAction.java:177)

at java.util.HashMap.forEach(HashMap.java:1290)

at
org.apache.cayenne.access.flush.DefaultDataDomainFlushAction.executeQueries(
DefaultDataDomainFlushAction.java:176)

at org.apache.cayenne.access.flush.DefaultDataDomainFlushAction.flush(
DefaultDataDomainFlushAction.java:89)

at org.apache.cayenne.access.DataDomain.onSyncFlush(DataDomain.java:637)

at org.apache.cayenne.access.DataDomain.onSyncNoFilters(DataDomain.java:609)

at org.apache.cayenne.access.DataDomain$DataDomainSyncFilterChain.onSync(
DataDomain.java:835)

at org.apache.cayenne.tx.TransactionFilter.lambda$onSync$0(
TransactionFilter.java:61)

at
org.apache.cayenne.tx.DefaultTransactionManager$BaseTransactionHandler.performInTransaction(
DefaultTransactionManager.java:180)

at
org.apache.cayenne.tx.DefaultTransactionManager$BaseTransactionHandler.performInNewTransaction(
DefaultTransactionManager.java:152)

at
org.apache.cayenne.tx.DefaultTransactionManager$NestedTransactionHandler.handle(
DefaultTransactionManager.java:95)

at org.apache.cayenne.tx.DefaultTransactionManager.performInTransaction(
DefaultTransactionManager.java:62)

at org.apache.cayenne.tx.DefaultTransactionManager.performInTransaction(
DefaultTransactionManager.java:40)

at org.apache.cayenne.tx.TransactionFilter.onSync(TransactionFilter.java:61)

at org.apache.cayenne.access.DataDomain$DataDomainSyncFilterChain.onSync(
DataDomain.java:834)

at org.apache.cayenne.access.DataDomain.onSync(DataDomain.java:596)

at org.apache.cayenne.access.DataContext.flushToParent(DataContext.java:737)

at org.apache.cayenne.access.DataContext.commitChanges(DataContext.java:686)

at com.smarthealth.cayennetest.App.main(App.java:38)

Nov 16 15:27:55 INFO  org.apache.cayenne.log.JdbcEventLogger  - ***
transaction rolledback.

org.apache.cayenne.CayenneRuntimeException: [v.4.2.M4-SNAPSHOT Nov 16 2021
22:12:02] Commit Exception

at org.apache.cayenne.access.DataContext.flushToParent(DataContext.java:769)

at org.apache.cayenne.access.DataContext.commitChanges(DataContext.java:686)

at com.smarthealth.cayennetest.App.main(App.java:38)

Caused by: java.lang.UnsupportedOperationException

at java.util.Collections$UnmodifiableMap.put(Collections.java:1459)

at org.apache.cayenne.query.BatchQueryRow.getValue(BatchQueryRow.java:80)

at org.apache.cayenne.query.UpdateBatchQuery$1.getValue(
UpdateBatchQuery.java:124)

at
org.apache.cayenne.access.translator.batch.UpdateBatchTranslator.updateBindings(
UpdateBatchTranslator.java:80)

at org.apache.cayenne.access.jdbc.BatchAction.runAsIndividualQueries(
BatchAction.java:191)

at org.apache.cayenne.access.jdbc.BatchAction.performAction(
BatchAction.java:93)

at org.apache.cayenne.access.DataNodeQueryAction.runQuery(
DataNodeQueryAction.java:97)

at org.apache.cayenne.access.DataNode.performQueries(DataNode.java:273)

at
org.apache.cayenne.access.flush.DefaultDataDomainFlushAction.lambda$executeQueries$6(
DefaultDataDomainFlushAction.java:177)

at java.util.HashMap.forEach(HashMap.java:1290)

at
org.apache.cayenne.access.flush.DefaultDataDomainFlushAction.executeQueries(
DefaultDataDomainFlushAction.java:176)

at org.apache.cayenne.access.flush.DefaultDataDomainFlushAction.flush(
DefaultDataDomainFlushAction.java:89)

at org.apache.cayenne.access.DataDomain.onSyncFlush(DataDomain.java:637)

at org.apache.cayenne.access.DataDomain.onSyncNoFilters(DataDomain.java:609)

at org.apache.cayenne.access.DataDomain$DataDomainSyncFilterChain.onSync(
DataDomain.java:835)

at org.apache.cayenne.tx.TransactionFilter.lambda$onSync$0(
TransactionFilter.java:61)

at
org.apache.cayenne.tx.DefaultTransactionManager$BaseTransactionHandler.performInTransaction(
DefaultTransactionManager.java:180)

at
org.apache.cayenne.tx.DefaultTransactionManager$BaseTransactionHandler.performInNewTransaction(
DefaultTransactionManager.java:152)

at
org.apache.cayenne.tx.DefaultTransactionManager$NestedTransactionHandler.handle(
DefaultTransactionManager.java:95)

at org.apache.cayenne.tx.DefaultTransactionManager.performInTransaction(
DefaultTransactionManager.java:62)

at org.apache.cayenne.tx.DefaultTransactionManager.performInTransaction(
DefaultTransactionManager.java:40)

at org.apache.cayenne.tx.TransactionFilter.onSync(TransactionFilter.java:61)

at org.apache.cayenne.access.DataDomain$DataDomainSyncFilterChain.onSync(
DataDomain.java:834)

at org.apache.cayenne.access.DataDomain.onSync(DataDomain.java:596)

at org.apache.cayenne.access.DataContext.flushToParent(DataContext.java:737)

... 2 more

Re: Problem with optional to-one deletion

Posted by Lon Varscsak <lo...@gmail.com>.
Hey Michael, thanks for responding..I just saw this.  Isn't  a one-to-many
where the dependent object (order_detail_sales) can't existing without the
master object (order_header) the right place to use the "to dep pk"
checkbox?  I have it like this everywhere. :P

On Wed, Nov 17, 2021 at 10:45 AM Michael Gentry <bl...@gmail.com> wrote:

> Hi Lon,
>
> I didn't have a lot of time to look into it, but I suspect it may be in
> your PK/FK mapping on the DbEntities.
>
> For example, in order_header, you have order_header ->> order_detail_sales,
> but you've mapped that as To-Many AND To-Dependent PK, which doesn't make
> sense.
>
>
> On Tue, Nov 16, 2021 at 6:14 PM Lon Varscsak <lo...@gmail.com>
> wrote:
>
> > I forgot to mention that I'm running 4.2.M4-SNAPSHOT (updated from github
> > as of an hour ago).
> >
> > On Tue, Nov 16, 2021 at 4:06 PM Lon Varscsak <lo...@gmail.com>
> > wrote:
> >
> > > Hey all,
> > >
> > > I have a setup where I have an optional to-one relationship, but when I
> > > try to clear the relationship and commitChanges, I get a low-level
> > Cayenne
> > > error along with some in appropriate sql generated.
> > >
> > > where it's doing an UPDATE to order_detail_costs should be a no-op,
> > > because the object was removed from it's parent (order_detail_sales)
> with
> > > setOrderDetailCost(null) along with a
> > > objectContext.deleteObject(orderDetailCost).  This is probably a
> problem
> > > for Nikita to look at, but I figured someone else may have run into
> this
> > as
> > > well.  It's unusual for me to have optional to-one relationships, but
> it
> > > does happen.
> > >
> > > Here is a sample project (Debug As -> Java Application) to try (link to
> > my
> > > Synology):
> > >
> >
> https://varscsak.synology.me:5001/d/s/mI7SBS6fApoUMNT1K5lfpaCXHKEkHkgd/jIy5Ug64Hjp2ieZzOceknc39sjBasJLE-T74gPgqKEgk
> > >
> > > ...snip...
> > >
> > > Nov 16 15:27:55 INFO  org.apache.cayenne.log.JdbcEventLogger  - INSERT
> > > INTO "order_header"( "attribute_1", "attribute_2", "order_number")
> > VALUES(
> > > ?, ?, ?)
> > >
> > > Nov 16 15:27:55 INFO  org.apache.cayenne.log.JdbcEventLogger  - [bind:
> > > 1->attribute_1:'TEST1', 2->attribute_2:1, 3->order_number:1]
> > >
> > > Nov 16 15:27:55 INFO  org.apache.cayenne.log.JdbcEventLogger  - ===
> > > updated 1 row.
> > >
> > > Nov 16 15:27:55 INFO  org.apache.cayenne.log.JdbcEventLogger  - INSERT
> > > INTO "order_detail_sales"( "detail_attr_1", "detail_attr_2",
> > > "order_line_number", "order_number") VALUES( ?, ?, ?, ?)
> > >
> > > Nov 16 15:27:55 INFO  org.apache.cayenne.log.JdbcEventLogger  - [bind:
> > > 1->detail_attr_1:'TEST1', 2->detail_attr_2:1, 3->order_line_number:1,
> > > 4->order_number:1]
> > >
> > > Nov 16 15:27:55 INFO  org.apache.cayenne.log.JdbcEventLogger  - ===
> > > updated 1 row.
> > >
> > > Nov 16 15:27:55 INFO  org.apache.cayenne.log.JdbcEventLogger  - UPDATE
> > > "order_detail_costs" SET "order_number" = ?, "order_line_number" = ?
> > WHERE
> > > ( "order_line_number" = ? ) AND ( "order_number" = ? )
> > >
> > > Nov 16 15:27:55 INFO  org.apache.cayenne.log.JdbcEventLogger  - ***
> > error.
> > >
> > > java.lang.UnsupportedOperationException
> > >
> > > at java.util.Collections$UnmodifiableMap.put(Collections.java:1459)
> > >
> > > at
> org.apache.cayenne.query.BatchQueryRow.getValue(BatchQueryRow.java:80)
> > >
> > > at org.apache.cayenne.query.UpdateBatchQuery$1.getValue(
> > > UpdateBatchQuery.java:124)
> > >
> > > at
> > >
> >
> org.apache.cayenne.access.translator.batch.UpdateBatchTranslator.updateBindings(
> > > UpdateBatchTranslator.java:80)
> > >
> > > at org.apache.cayenne.access.jdbc.BatchAction.runAsIndividualQueries(
> > > BatchAction.java:191)
> > >
> > > at org.apache.cayenne.access.jdbc.BatchAction.performAction(
> > > BatchAction.java:93)
> > >
> > > at org.apache.cayenne.access.DataNodeQueryAction.runQuery(
> > > DataNodeQueryAction.java:97)
> > >
> > > at org.apache.cayenne.access.DataNode.performQueries(DataNode.java:273)
> > >
> > > at
> > >
> >
> org.apache.cayenne.access.flush.DefaultDataDomainFlushAction.lambda$executeQueries$6(
> > > DefaultDataDomainFlushAction.java:177)
> > >
> > > at java.util.HashMap.forEach(HashMap.java:1290)
> > >
> > > at
> > >
> >
> org.apache.cayenne.access.flush.DefaultDataDomainFlushAction.executeQueries(
> > > DefaultDataDomainFlushAction.java:176)
> > >
> > > at org.apache.cayenne.access.flush.DefaultDataDomainFlushAction.flush(
> > > DefaultDataDomainFlushAction.java:89)
> > >
> > > at
> org.apache.cayenne.access.DataDomain.onSyncFlush(DataDomain.java:637)
> > >
> > > at org.apache.cayenne.access.DataDomain.onSyncNoFilters(
> > > DataDomain.java:609)
> > >
> > > at
> org.apache.cayenne.access.DataDomain$DataDomainSyncFilterChain.onSync(
> > > DataDomain.java:835)
> > >
> > > at org.apache.cayenne.tx.TransactionFilter.lambda$onSync$0(
> > > TransactionFilter.java:61)
> > >
> > > at
> > >
> >
> org.apache.cayenne.tx.DefaultTransactionManager$BaseTransactionHandler.performInTransaction(
> > > DefaultTransactionManager.java:180)
> > >
> > > at
> > >
> >
> org.apache.cayenne.tx.DefaultTransactionManager$BaseTransactionHandler.performInNewTransaction(
> > > DefaultTransactionManager.java:152)
> > >
> > > at
> > >
> >
> org.apache.cayenne.tx.DefaultTransactionManager$NestedTransactionHandler.handle(
> > > DefaultTransactionManager.java:95)
> > >
> > > at
> org.apache.cayenne.tx.DefaultTransactionManager.performInTransaction(
> > > DefaultTransactionManager.java:62)
> > >
> > > at
> org.apache.cayenne.tx.DefaultTransactionManager.performInTransaction(
> > > DefaultTransactionManager.java:40)
> > >
> > > at org.apache.cayenne.tx.TransactionFilter.onSync(
> > > TransactionFilter.java:61)
> > >
> > > at
> org.apache.cayenne.access.DataDomain$DataDomainSyncFilterChain.onSync(
> > > DataDomain.java:834)
> > >
> > > at org.apache.cayenne.access.DataDomain.onSync(DataDomain.java:596)
> > >
> > > at org.apache.cayenne.access.DataContext.flushToParent(
> > > DataContext.java:737)
> > >
> > > at org.apache.cayenne.access.DataContext.commitChanges(
> > > DataContext.java:686)
> > >
> > > at com.smarthealth.cayennetest.App.main(App.java:38)
> > >
> > > Nov 16 15:27:55 INFO  org.apache.cayenne.log.JdbcEventLogger  - ***
> > > transaction rolledback.
> > >
> > > org.apache.cayenne.CayenneRuntimeException: [v.4.2.M4-SNAPSHOT Nov 16
> > > 2021 22:12:02] Commit Exception
> > >
> > > at org.apache.cayenne.access.DataContext.flushToParent(
> > > DataContext.java:769)
> > >
> > > at org.apache.cayenne.access.DataContext.commitChanges(
> > > DataContext.java:686)
> > >
> > > at com.smarthealth.cayennetest.App.main(App.java:38)
> > >
> > > Caused by: java.lang.UnsupportedOperationException
> > >
> > > at java.util.Collections$UnmodifiableMap.put(Collections.java:1459)
> > >
> > > at
> org.apache.cayenne.query.BatchQueryRow.getValue(BatchQueryRow.java:80)
> > >
> > > at org.apache.cayenne.query.UpdateBatchQuery$1.getValue(
> > > UpdateBatchQuery.java:124)
> > >
> > > at
> > >
> >
> org.apache.cayenne.access.translator.batch.UpdateBatchTranslator.updateBindings(
> > > UpdateBatchTranslator.java:80)
> > >
> > > at org.apache.cayenne.access.jdbc.BatchAction.runAsIndividualQueries(
> > > BatchAction.java:191)
> > >
> > > at org.apache.cayenne.access.jdbc.BatchAction.performAction(
> > > BatchAction.java:93)
> > >
> > > at org.apache.cayenne.access.DataNodeQueryAction.runQuery(
> > > DataNodeQueryAction.java:97)
> > >
> > > at org.apache.cayenne.access.DataNode.performQueries(DataNode.java:273)
> > >
> > > at
> > >
> >
> org.apache.cayenne.access.flush.DefaultDataDomainFlushAction.lambda$executeQueries$6(
> > > DefaultDataDomainFlushAction.java:177)
> > >
> > > at java.util.HashMap.forEach(HashMap.java:1290)
> > >
> > > at
> > >
> >
> org.apache.cayenne.access.flush.DefaultDataDomainFlushAction.executeQueries(
> > > DefaultDataDomainFlushAction.java:176)
> > >
> > > at org.apache.cayenne.access.flush.DefaultDataDomainFlushAction.flush(
> > > DefaultDataDomainFlushAction.java:89)
> > >
> > > at
> org.apache.cayenne.access.DataDomain.onSyncFlush(DataDomain.java:637)
> > >
> > > at org.apache.cayenne.access.DataDomain.onSyncNoFilters(
> > > DataDomain.java:609)
> > >
> > > at
> org.apache.cayenne.access.DataDomain$DataDomainSyncFilterChain.onSync(
> > > DataDomain.java:835)
> > >
> > > at org.apache.cayenne.tx.TransactionFilter.lambda$onSync$0(
> > > TransactionFilter.java:61)
> > >
> > > at
> > >
> >
> org.apache.cayenne.tx.DefaultTransactionManager$BaseTransactionHandler.performInTransaction(
> > > DefaultTransactionManager.java:180)
> > >
> > > at
> > >
> >
> org.apache.cayenne.tx.DefaultTransactionManager$BaseTransactionHandler.performInNewTransaction(
> > > DefaultTransactionManager.java:152)
> > >
> > > at
> > >
> >
> org.apache.cayenne.tx.DefaultTransactionManager$NestedTransactionHandler.handle(
> > > DefaultTransactionManager.java:95)
> > >
> > > at
> org.apache.cayenne.tx.DefaultTransactionManager.performInTransaction(
> > > DefaultTransactionManager.java:62)
> > >
> > > at
> org.apache.cayenne.tx.DefaultTransactionManager.performInTransaction(
> > > DefaultTransactionManager.java:40)
> > >
> > > at org.apache.cayenne.tx.TransactionFilter.onSync(
> > > TransactionFilter.java:61)
> > >
> > > at
> org.apache.cayenne.access.DataDomain$DataDomainSyncFilterChain.onSync(
> > > DataDomain.java:834)
> > >
> > > at org.apache.cayenne.access.DataDomain.onSync(DataDomain.java:596)
> > >
> > > at org.apache.cayenne.access.DataContext.flushToParent(
> > > DataContext.java:737)
> > >
> > > ... 2 more
> > >
> > >
> > >
> >
>

Re: Problem with optional to-one deletion

Posted by Lon Varscsak <lo...@gmail.com>.
You're a superstar! :)

On Tue, Nov 23, 2021 at 11:28 AM Nikita Timofeev <nt...@objectstyle.com>
wrote:

> Hi all,
>
> Thanks, Lon for the report and an excellent example, that really
> helped to quickly find the problem [1].
> It should be fixed now.
>
> Sorry, Michael for not notifying that I dived into this, just grabbed
> the test case and started debugging :)
>
> [1] https://issues.apache.org/jira/browse/CAY-2723
>
> On Wed, Nov 17, 2021 at 9:25 PM Michael Gentry <bl...@gmail.com>
> wrote:
> >
> > OK, nice to know. I won't dive into it more this evening, then.
> >
> > Thanks!
> >
> >
> > On Wed, Nov 17, 2021 at 1:04 PM Andrus Adamchik <aa...@gmail.com>
> wrote:
> >
> > > Hi Mike,
> > >
> > > Nikita mentioned a few hours ago that he was able to reproduce.
> Appears to
> > > be a bug in the 4.2 stack.
> > >
> > > Andrus
> > >
> > > > On Nov 17, 2021, at 7:44 PM, Michael Gentry <bl...@gmail.com>
> wrote:
> > > >
> > > > Hi Lon,
> > > >
> > > > I didn't have a lot of time to look into it, but I suspect it may be
> in
> > > > your PK/FK mapping on the DbEntities.
> > > >
> > > > For example, in order_header, you have order_header ->>
> > > order_detail_sales,
> > > > but you've mapped that as To-Many AND To-Dependent PK, which doesn't
> make
> > > > sense.
> > > >
> > > >
> > > > On Tue, Nov 16, 2021 at 6:14 PM Lon Varscsak <lon.varscsak@gmail.com
> >
> > > wrote:
> > > >
> > > >> I forgot to mention that I'm running 4.2.M4-SNAPSHOT (updated from
> > > github
> > > >> as of an hour ago).
> > > >>
> > > >> On Tue, Nov 16, 2021 at 4:06 PM Lon Varscsak <
> lon.varscsak@gmail.com>
> > > >> wrote:
> > > >>
> > > >>> Hey all,
> > > >>>
> > > >>> I have a setup where I have an optional to-one relationship, but
> when I
> > > >>> try to clear the relationship and commitChanges, I get a low-level
> > > >> Cayenne
> > > >>> error along with some in appropriate sql generated.
> > > >>>
> > > >>> where it's doing an UPDATE to order_detail_costs should be a no-op,
> > > >>> because the object was removed from it's parent
> (order_detail_sales)
> > > with
> > > >>> setOrderDetailCost(null) along with a
> > > >>> objectContext.deleteObject(orderDetailCost).  This is probably a
> > > problem
> > > >>> for Nikita to look at, but I figured someone else may have run into
> > > this
> > > >> as
> > > >>> well.  It's unusual for me to have optional to-one relationships,
> but
> > > it
> > > >>> does happen.
> > > >>>
> > > >>> Here is a sample project (Debug As -> Java Application) to try
> (link to
> > > >> my
> > > >>> Synology):
> > > >>>
> > > >>
> > >
> https://varscsak.synology.me:5001/d/s/mI7SBS6fApoUMNT1K5lfpaCXHKEkHkgd/jIy5Ug64Hjp2ieZzOceknc39sjBasJLE-T74gPgqKEgk
> > > >>>
> > > >>> ...snip...
> > > >>>
> > > >>> Nov 16 15:27:55 INFO  org.apache.cayenne.log.JdbcEventLogger  -
> INSERT
> > > >>> INTO "order_header"( "attribute_1", "attribute_2", "order_number")
> > > >> VALUES(
> > > >>> ?, ?, ?)
> > > >>>
> > > >>> Nov 16 15:27:55 INFO  org.apache.cayenne.log.JdbcEventLogger  -
> [bind:
> > > >>> 1->attribute_1:'TEST1', 2->attribute_2:1, 3->order_number:1]
> > > >>>
> > > >>> Nov 16 15:27:55 INFO  org.apache.cayenne.log.JdbcEventLogger  - ===
> > > >>> updated 1 row.
> > > >>>
> > > >>> Nov 16 15:27:55 INFO  org.apache.cayenne.log.JdbcEventLogger  -
> INSERT
> > > >>> INTO "order_detail_sales"( "detail_attr_1", "detail_attr_2",
> > > >>> "order_line_number", "order_number") VALUES( ?, ?, ?, ?)
> > > >>>
> > > >>> Nov 16 15:27:55 INFO  org.apache.cayenne.log.JdbcEventLogger  -
> [bind:
> > > >>> 1->detail_attr_1:'TEST1', 2->detail_attr_2:1,
> 3->order_line_number:1,
> > > >>> 4->order_number:1]
> > > >>>
> > > >>> Nov 16 15:27:55 INFO  org.apache.cayenne.log.JdbcEventLogger  - ===
> > > >>> updated 1 row.
> > > >>>
> > > >>> Nov 16 15:27:55 INFO  org.apache.cayenne.log.JdbcEventLogger  -
> UPDATE
> > > >>> "order_detail_costs" SET "order_number" = ?, "order_line_number" =
> ?
> > > >> WHERE
> > > >>> ( "order_line_number" = ? ) AND ( "order_number" = ? )
> > > >>>
> > > >>> Nov 16 15:27:55 INFO  org.apache.cayenne.log.JdbcEventLogger  - ***
> > > >> error.
> > > >>>
> > > >>> java.lang.UnsupportedOperationException
> > > >>>
> > > >>> at java.util.Collections$UnmodifiableMap.put(Collections.java:1459)
> > > >>>
> > > >>> at
> > > org.apache.cayenne.query.BatchQueryRow.getValue(BatchQueryRow.java:80)
> > > >>>
> > > >>> at org.apache.cayenne.query.UpdateBatchQuery$1.getValue(
> > > >>> UpdateBatchQuery.java:124)
> > > >>>
> > > >>> at
> > > >>>
> > > >>
> > >
> org.apache.cayenne.access.translator.batch.UpdateBatchTranslator.updateBindings(
> > > >>> UpdateBatchTranslator.java:80)
> > > >>>
> > > >>> at
> org.apache.cayenne.access.jdbc.BatchAction.runAsIndividualQueries(
> > > >>> BatchAction.java:191)
> > > >>>
> > > >>> at org.apache.cayenne.access.jdbc.BatchAction.performAction(
> > > >>> BatchAction.java:93)
> > > >>>
> > > >>> at org.apache.cayenne.access.DataNodeQueryAction.runQuery(
> > > >>> DataNodeQueryAction.java:97)
> > > >>>
> > > >>> at
> org.apache.cayenne.access.DataNode.performQueries(DataNode.java:273)
> > > >>>
> > > >>> at
> > > >>>
> > > >>
> > >
> org.apache.cayenne.access.flush.DefaultDataDomainFlushAction.lambda$executeQueries$6(
> > > >>> DefaultDataDomainFlushAction.java:177)
> > > >>>
> > > >>> at java.util.HashMap.forEach(HashMap.java:1290)
> > > >>>
> > > >>> at
> > > >>>
> > > >>
> > >
> org.apache.cayenne.access.flush.DefaultDataDomainFlushAction.executeQueries(
> > > >>> DefaultDataDomainFlushAction.java:176)
> > > >>>
> > > >>> at
> org.apache.cayenne.access.flush.DefaultDataDomainFlushAction.flush(
> > > >>> DefaultDataDomainFlushAction.java:89)
> > > >>>
> > > >>> at
> > > org.apache.cayenne.access.DataDomain.onSyncFlush(DataDomain.java:637)
> > > >>>
> > > >>> at org.apache.cayenne.access.DataDomain.onSyncNoFilters(
> > > >>> DataDomain.java:609)
> > > >>>
> > > >>> at
> > > org.apache.cayenne.access.DataDomain$DataDomainSyncFilterChain.onSync(
> > > >>> DataDomain.java:835)
> > > >>>
> > > >>> at org.apache.cayenne.tx.TransactionFilter.lambda$onSync$0(
> > > >>> TransactionFilter.java:61)
> > > >>>
> > > >>> at
> > > >>>
> > > >>
> > >
> org.apache.cayenne.tx.DefaultTransactionManager$BaseTransactionHandler.performInTransaction(
> > > >>> DefaultTransactionManager.java:180)
> > > >>>
> > > >>> at
> > > >>>
> > > >>
> > >
> org.apache.cayenne.tx.DefaultTransactionManager$BaseTransactionHandler.performInNewTransaction(
> > > >>> DefaultTransactionManager.java:152)
> > > >>>
> > > >>> at
> > > >>>
> > > >>
> > >
> org.apache.cayenne.tx.DefaultTransactionManager$NestedTransactionHandler.handle(
> > > >>> DefaultTransactionManager.java:95)
> > > >>>
> > > >>> at
> > > org.apache.cayenne.tx.DefaultTransactionManager.performInTransaction(
> > > >>> DefaultTransactionManager.java:62)
> > > >>>
> > > >>> at
> > > org.apache.cayenne.tx.DefaultTransactionManager.performInTransaction(
> > > >>> DefaultTransactionManager.java:40)
> > > >>>
> > > >>> at org.apache.cayenne.tx.TransactionFilter.onSync(
> > > >>> TransactionFilter.java:61)
> > > >>>
> > > >>> at
> > > org.apache.cayenne.access.DataDomain$DataDomainSyncFilterChain.onSync(
> > > >>> DataDomain.java:834)
> > > >>>
> > > >>> at org.apache.cayenne.access.DataDomain.onSync(DataDomain.java:596)
> > > >>>
> > > >>> at org.apache.cayenne.access.DataContext.flushToParent(
> > > >>> DataContext.java:737)
> > > >>>
> > > >>> at org.apache.cayenne.access.DataContext.commitChanges(
> > > >>> DataContext.java:686)
> > > >>>
> > > >>> at com.smarthealth.cayennetest.App.main(App.java:38)
> > > >>>
> > > >>> Nov 16 15:27:55 INFO  org.apache.cayenne.log.JdbcEventLogger  - ***
> > > >>> transaction rolledback.
> > > >>>
> > > >>> org.apache.cayenne.CayenneRuntimeException: [v.4.2.M4-SNAPSHOT Nov
> 16
> > > >>> 2021 22:12:02] Commit Exception
> > > >>>
> > > >>> at org.apache.cayenne.access.DataContext.flushToParent(
> > > >>> DataContext.java:769)
> > > >>>
> > > >>> at org.apache.cayenne.access.DataContext.commitChanges(
> > > >>> DataContext.java:686)
> > > >>>
> > > >>> at com.smarthealth.cayennetest.App.main(App.java:38)
> > > >>>
> > > >>> Caused by: java.lang.UnsupportedOperationException
> > > >>>
> > > >>> at java.util.Collections$UnmodifiableMap.put(Collections.java:1459)
> > > >>>
> > > >>> at
> > > org.apache.cayenne.query.BatchQueryRow.getValue(BatchQueryRow.java:80)
> > > >>>
> > > >>> at org.apache.cayenne.query.UpdateBatchQuery$1.getValue(
> > > >>> UpdateBatchQuery.java:124)
> > > >>>
> > > >>> at
> > > >>>
> > > >>
> > >
> org.apache.cayenne.access.translator.batch.UpdateBatchTranslator.updateBindings(
> > > >>> UpdateBatchTranslator.java:80)
> > > >>>
> > > >>> at
> org.apache.cayenne.access.jdbc.BatchAction.runAsIndividualQueries(
> > > >>> BatchAction.java:191)
> > > >>>
> > > >>> at org.apache.cayenne.access.jdbc.BatchAction.performAction(
> > > >>> BatchAction.java:93)
> > > >>>
> > > >>> at org.apache.cayenne.access.DataNodeQueryAction.runQuery(
> > > >>> DataNodeQueryAction.java:97)
> > > >>>
> > > >>> at
> org.apache.cayenne.access.DataNode.performQueries(DataNode.java:273)
> > > >>>
> > > >>> at
> > > >>>
> > > >>
> > >
> org.apache.cayenne.access.flush.DefaultDataDomainFlushAction.lambda$executeQueries$6(
> > > >>> DefaultDataDomainFlushAction.java:177)
> > > >>>
> > > >>> at java.util.HashMap.forEach(HashMap.java:1290)
> > > >>>
> > > >>> at
> > > >>>
> > > >>
> > >
> org.apache.cayenne.access.flush.DefaultDataDomainFlushAction.executeQueries(
> > > >>> DefaultDataDomainFlushAction.java:176)
> > > >>>
> > > >>> at
> org.apache.cayenne.access.flush.DefaultDataDomainFlushAction.flush(
> > > >>> DefaultDataDomainFlushAction.java:89)
> > > >>>
> > > >>> at
> > > org.apache.cayenne.access.DataDomain.onSyncFlush(DataDomain.java:637)
> > > >>>
> > > >>> at org.apache.cayenne.access.DataDomain.onSyncNoFilters(
> > > >>> DataDomain.java:609)
> > > >>>
> > > >>> at
> > > org.apache.cayenne.access.DataDomain$DataDomainSyncFilterChain.onSync(
> > > >>> DataDomain.java:835)
> > > >>>
> > > >>> at org.apache.cayenne.tx.TransactionFilter.lambda$onSync$0(
> > > >>> TransactionFilter.java:61)
> > > >>>
> > > >>> at
> > > >>>
> > > >>
> > >
> org.apache.cayenne.tx.DefaultTransactionManager$BaseTransactionHandler.performInTransaction(
> > > >>> DefaultTransactionManager.java:180)
> > > >>>
> > > >>> at
> > > >>>
> > > >>
> > >
> org.apache.cayenne.tx.DefaultTransactionManager$BaseTransactionHandler.performInNewTransaction(
> > > >>> DefaultTransactionManager.java:152)
> > > >>>
> > > >>> at
> > > >>>
> > > >>
> > >
> org.apache.cayenne.tx.DefaultTransactionManager$NestedTransactionHandler.handle(
> > > >>> DefaultTransactionManager.java:95)
> > > >>>
> > > >>> at
> > > org.apache.cayenne.tx.DefaultTransactionManager.performInTransaction(
> > > >>> DefaultTransactionManager.java:62)
> > > >>>
> > > >>> at
> > > org.apache.cayenne.tx.DefaultTransactionManager.performInTransaction(
> > > >>> DefaultTransactionManager.java:40)
> > > >>>
> > > >>> at org.apache.cayenne.tx.TransactionFilter.onSync(
> > > >>> TransactionFilter.java:61)
> > > >>>
> > > >>> at
> > > org.apache.cayenne.access.DataDomain$DataDomainSyncFilterChain.onSync(
> > > >>> DataDomain.java:834)
> > > >>>
> > > >>> at org.apache.cayenne.access.DataDomain.onSync(DataDomain.java:596)
> > > >>>
> > > >>> at org.apache.cayenne.access.DataContext.flushToParent(
> > > >>> DataContext.java:737)
> > > >>>
> > > >>> ... 2 more
> > > >>>
> > > >>>
> > > >>>
> > > >>
> > >
> > >
>
>
>
> --
> Best regards,
> Nikita Timofeev
>

Re: Problem with optional to-one deletion

Posted by Nikita Timofeev <nt...@objectstyle.com>.
Hi all,

Thanks, Lon for the report and an excellent example, that really
helped to quickly find the problem [1].
It should be fixed now.

Sorry, Michael for not notifying that I dived into this, just grabbed
the test case and started debugging :)

[1] https://issues.apache.org/jira/browse/CAY-2723

On Wed, Nov 17, 2021 at 9:25 PM Michael Gentry <bl...@gmail.com> wrote:
>
> OK, nice to know. I won't dive into it more this evening, then.
>
> Thanks!
>
>
> On Wed, Nov 17, 2021 at 1:04 PM Andrus Adamchik <aa...@gmail.com> wrote:
>
> > Hi Mike,
> >
> > Nikita mentioned a few hours ago that he was able to reproduce. Appears to
> > be a bug in the 4.2 stack.
> >
> > Andrus
> >
> > > On Nov 17, 2021, at 7:44 PM, Michael Gentry <bl...@gmail.com> wrote:
> > >
> > > Hi Lon,
> > >
> > > I didn't have a lot of time to look into it, but I suspect it may be in
> > > your PK/FK mapping on the DbEntities.
> > >
> > > For example, in order_header, you have order_header ->>
> > order_detail_sales,
> > > but you've mapped that as To-Many AND To-Dependent PK, which doesn't make
> > > sense.
> > >
> > >
> > > On Tue, Nov 16, 2021 at 6:14 PM Lon Varscsak <lo...@gmail.com>
> > wrote:
> > >
> > >> I forgot to mention that I'm running 4.2.M4-SNAPSHOT (updated from
> > github
> > >> as of an hour ago).
> > >>
> > >> On Tue, Nov 16, 2021 at 4:06 PM Lon Varscsak <lo...@gmail.com>
> > >> wrote:
> > >>
> > >>> Hey all,
> > >>>
> > >>> I have a setup where I have an optional to-one relationship, but when I
> > >>> try to clear the relationship and commitChanges, I get a low-level
> > >> Cayenne
> > >>> error along with some in appropriate sql generated.
> > >>>
> > >>> where it's doing an UPDATE to order_detail_costs should be a no-op,
> > >>> because the object was removed from it's parent (order_detail_sales)
> > with
> > >>> setOrderDetailCost(null) along with a
> > >>> objectContext.deleteObject(orderDetailCost).  This is probably a
> > problem
> > >>> for Nikita to look at, but I figured someone else may have run into
> > this
> > >> as
> > >>> well.  It's unusual for me to have optional to-one relationships, but
> > it
> > >>> does happen.
> > >>>
> > >>> Here is a sample project (Debug As -> Java Application) to try (link to
> > >> my
> > >>> Synology):
> > >>>
> > >>
> > https://varscsak.synology.me:5001/d/s/mI7SBS6fApoUMNT1K5lfpaCXHKEkHkgd/jIy5Ug64Hjp2ieZzOceknc39sjBasJLE-T74gPgqKEgk
> > >>>
> > >>> ...snip...
> > >>>
> > >>> Nov 16 15:27:55 INFO  org.apache.cayenne.log.JdbcEventLogger  - INSERT
> > >>> INTO "order_header"( "attribute_1", "attribute_2", "order_number")
> > >> VALUES(
> > >>> ?, ?, ?)
> > >>>
> > >>> Nov 16 15:27:55 INFO  org.apache.cayenne.log.JdbcEventLogger  - [bind:
> > >>> 1->attribute_1:'TEST1', 2->attribute_2:1, 3->order_number:1]
> > >>>
> > >>> Nov 16 15:27:55 INFO  org.apache.cayenne.log.JdbcEventLogger  - ===
> > >>> updated 1 row.
> > >>>
> > >>> Nov 16 15:27:55 INFO  org.apache.cayenne.log.JdbcEventLogger  - INSERT
> > >>> INTO "order_detail_sales"( "detail_attr_1", "detail_attr_2",
> > >>> "order_line_number", "order_number") VALUES( ?, ?, ?, ?)
> > >>>
> > >>> Nov 16 15:27:55 INFO  org.apache.cayenne.log.JdbcEventLogger  - [bind:
> > >>> 1->detail_attr_1:'TEST1', 2->detail_attr_2:1, 3->order_line_number:1,
> > >>> 4->order_number:1]
> > >>>
> > >>> Nov 16 15:27:55 INFO  org.apache.cayenne.log.JdbcEventLogger  - ===
> > >>> updated 1 row.
> > >>>
> > >>> Nov 16 15:27:55 INFO  org.apache.cayenne.log.JdbcEventLogger  - UPDATE
> > >>> "order_detail_costs" SET "order_number" = ?, "order_line_number" = ?
> > >> WHERE
> > >>> ( "order_line_number" = ? ) AND ( "order_number" = ? )
> > >>>
> > >>> Nov 16 15:27:55 INFO  org.apache.cayenne.log.JdbcEventLogger  - ***
> > >> error.
> > >>>
> > >>> java.lang.UnsupportedOperationException
> > >>>
> > >>> at java.util.Collections$UnmodifiableMap.put(Collections.java:1459)
> > >>>
> > >>> at
> > org.apache.cayenne.query.BatchQueryRow.getValue(BatchQueryRow.java:80)
> > >>>
> > >>> at org.apache.cayenne.query.UpdateBatchQuery$1.getValue(
> > >>> UpdateBatchQuery.java:124)
> > >>>
> > >>> at
> > >>>
> > >>
> > org.apache.cayenne.access.translator.batch.UpdateBatchTranslator.updateBindings(
> > >>> UpdateBatchTranslator.java:80)
> > >>>
> > >>> at org.apache.cayenne.access.jdbc.BatchAction.runAsIndividualQueries(
> > >>> BatchAction.java:191)
> > >>>
> > >>> at org.apache.cayenne.access.jdbc.BatchAction.performAction(
> > >>> BatchAction.java:93)
> > >>>
> > >>> at org.apache.cayenne.access.DataNodeQueryAction.runQuery(
> > >>> DataNodeQueryAction.java:97)
> > >>>
> > >>> at org.apache.cayenne.access.DataNode.performQueries(DataNode.java:273)
> > >>>
> > >>> at
> > >>>
> > >>
> > org.apache.cayenne.access.flush.DefaultDataDomainFlushAction.lambda$executeQueries$6(
> > >>> DefaultDataDomainFlushAction.java:177)
> > >>>
> > >>> at java.util.HashMap.forEach(HashMap.java:1290)
> > >>>
> > >>> at
> > >>>
> > >>
> > org.apache.cayenne.access.flush.DefaultDataDomainFlushAction.executeQueries(
> > >>> DefaultDataDomainFlushAction.java:176)
> > >>>
> > >>> at org.apache.cayenne.access.flush.DefaultDataDomainFlushAction.flush(
> > >>> DefaultDataDomainFlushAction.java:89)
> > >>>
> > >>> at
> > org.apache.cayenne.access.DataDomain.onSyncFlush(DataDomain.java:637)
> > >>>
> > >>> at org.apache.cayenne.access.DataDomain.onSyncNoFilters(
> > >>> DataDomain.java:609)
> > >>>
> > >>> at
> > org.apache.cayenne.access.DataDomain$DataDomainSyncFilterChain.onSync(
> > >>> DataDomain.java:835)
> > >>>
> > >>> at org.apache.cayenne.tx.TransactionFilter.lambda$onSync$0(
> > >>> TransactionFilter.java:61)
> > >>>
> > >>> at
> > >>>
> > >>
> > org.apache.cayenne.tx.DefaultTransactionManager$BaseTransactionHandler.performInTransaction(
> > >>> DefaultTransactionManager.java:180)
> > >>>
> > >>> at
> > >>>
> > >>
> > org.apache.cayenne.tx.DefaultTransactionManager$BaseTransactionHandler.performInNewTransaction(
> > >>> DefaultTransactionManager.java:152)
> > >>>
> > >>> at
> > >>>
> > >>
> > org.apache.cayenne.tx.DefaultTransactionManager$NestedTransactionHandler.handle(
> > >>> DefaultTransactionManager.java:95)
> > >>>
> > >>> at
> > org.apache.cayenne.tx.DefaultTransactionManager.performInTransaction(
> > >>> DefaultTransactionManager.java:62)
> > >>>
> > >>> at
> > org.apache.cayenne.tx.DefaultTransactionManager.performInTransaction(
> > >>> DefaultTransactionManager.java:40)
> > >>>
> > >>> at org.apache.cayenne.tx.TransactionFilter.onSync(
> > >>> TransactionFilter.java:61)
> > >>>
> > >>> at
> > org.apache.cayenne.access.DataDomain$DataDomainSyncFilterChain.onSync(
> > >>> DataDomain.java:834)
> > >>>
> > >>> at org.apache.cayenne.access.DataDomain.onSync(DataDomain.java:596)
> > >>>
> > >>> at org.apache.cayenne.access.DataContext.flushToParent(
> > >>> DataContext.java:737)
> > >>>
> > >>> at org.apache.cayenne.access.DataContext.commitChanges(
> > >>> DataContext.java:686)
> > >>>
> > >>> at com.smarthealth.cayennetest.App.main(App.java:38)
> > >>>
> > >>> Nov 16 15:27:55 INFO  org.apache.cayenne.log.JdbcEventLogger  - ***
> > >>> transaction rolledback.
> > >>>
> > >>> org.apache.cayenne.CayenneRuntimeException: [v.4.2.M4-SNAPSHOT Nov 16
> > >>> 2021 22:12:02] Commit Exception
> > >>>
> > >>> at org.apache.cayenne.access.DataContext.flushToParent(
> > >>> DataContext.java:769)
> > >>>
> > >>> at org.apache.cayenne.access.DataContext.commitChanges(
> > >>> DataContext.java:686)
> > >>>
> > >>> at com.smarthealth.cayennetest.App.main(App.java:38)
> > >>>
> > >>> Caused by: java.lang.UnsupportedOperationException
> > >>>
> > >>> at java.util.Collections$UnmodifiableMap.put(Collections.java:1459)
> > >>>
> > >>> at
> > org.apache.cayenne.query.BatchQueryRow.getValue(BatchQueryRow.java:80)
> > >>>
> > >>> at org.apache.cayenne.query.UpdateBatchQuery$1.getValue(
> > >>> UpdateBatchQuery.java:124)
> > >>>
> > >>> at
> > >>>
> > >>
> > org.apache.cayenne.access.translator.batch.UpdateBatchTranslator.updateBindings(
> > >>> UpdateBatchTranslator.java:80)
> > >>>
> > >>> at org.apache.cayenne.access.jdbc.BatchAction.runAsIndividualQueries(
> > >>> BatchAction.java:191)
> > >>>
> > >>> at org.apache.cayenne.access.jdbc.BatchAction.performAction(
> > >>> BatchAction.java:93)
> > >>>
> > >>> at org.apache.cayenne.access.DataNodeQueryAction.runQuery(
> > >>> DataNodeQueryAction.java:97)
> > >>>
> > >>> at org.apache.cayenne.access.DataNode.performQueries(DataNode.java:273)
> > >>>
> > >>> at
> > >>>
> > >>
> > org.apache.cayenne.access.flush.DefaultDataDomainFlushAction.lambda$executeQueries$6(
> > >>> DefaultDataDomainFlushAction.java:177)
> > >>>
> > >>> at java.util.HashMap.forEach(HashMap.java:1290)
> > >>>
> > >>> at
> > >>>
> > >>
> > org.apache.cayenne.access.flush.DefaultDataDomainFlushAction.executeQueries(
> > >>> DefaultDataDomainFlushAction.java:176)
> > >>>
> > >>> at org.apache.cayenne.access.flush.DefaultDataDomainFlushAction.flush(
> > >>> DefaultDataDomainFlushAction.java:89)
> > >>>
> > >>> at
> > org.apache.cayenne.access.DataDomain.onSyncFlush(DataDomain.java:637)
> > >>>
> > >>> at org.apache.cayenne.access.DataDomain.onSyncNoFilters(
> > >>> DataDomain.java:609)
> > >>>
> > >>> at
> > org.apache.cayenne.access.DataDomain$DataDomainSyncFilterChain.onSync(
> > >>> DataDomain.java:835)
> > >>>
> > >>> at org.apache.cayenne.tx.TransactionFilter.lambda$onSync$0(
> > >>> TransactionFilter.java:61)
> > >>>
> > >>> at
> > >>>
> > >>
> > org.apache.cayenne.tx.DefaultTransactionManager$BaseTransactionHandler.performInTransaction(
> > >>> DefaultTransactionManager.java:180)
> > >>>
> > >>> at
> > >>>
> > >>
> > org.apache.cayenne.tx.DefaultTransactionManager$BaseTransactionHandler.performInNewTransaction(
> > >>> DefaultTransactionManager.java:152)
> > >>>
> > >>> at
> > >>>
> > >>
> > org.apache.cayenne.tx.DefaultTransactionManager$NestedTransactionHandler.handle(
> > >>> DefaultTransactionManager.java:95)
> > >>>
> > >>> at
> > org.apache.cayenne.tx.DefaultTransactionManager.performInTransaction(
> > >>> DefaultTransactionManager.java:62)
> > >>>
> > >>> at
> > org.apache.cayenne.tx.DefaultTransactionManager.performInTransaction(
> > >>> DefaultTransactionManager.java:40)
> > >>>
> > >>> at org.apache.cayenne.tx.TransactionFilter.onSync(
> > >>> TransactionFilter.java:61)
> > >>>
> > >>> at
> > org.apache.cayenne.access.DataDomain$DataDomainSyncFilterChain.onSync(
> > >>> DataDomain.java:834)
> > >>>
> > >>> at org.apache.cayenne.access.DataDomain.onSync(DataDomain.java:596)
> > >>>
> > >>> at org.apache.cayenne.access.DataContext.flushToParent(
> > >>> DataContext.java:737)
> > >>>
> > >>> ... 2 more
> > >>>
> > >>>
> > >>>
> > >>
> >
> >



-- 
Best regards,
Nikita Timofeev

Re: Problem with optional to-one deletion

Posted by Michael Gentry <bl...@gmail.com>.
OK, nice to know. I won't dive into it more this evening, then.

Thanks!


On Wed, Nov 17, 2021 at 1:04 PM Andrus Adamchik <aa...@gmail.com> wrote:

> Hi Mike,
>
> Nikita mentioned a few hours ago that he was able to reproduce. Appears to
> be a bug in the 4.2 stack.
>
> Andrus
>
> > On Nov 17, 2021, at 7:44 PM, Michael Gentry <bl...@gmail.com> wrote:
> >
> > Hi Lon,
> >
> > I didn't have a lot of time to look into it, but I suspect it may be in
> > your PK/FK mapping on the DbEntities.
> >
> > For example, in order_header, you have order_header ->>
> order_detail_sales,
> > but you've mapped that as To-Many AND To-Dependent PK, which doesn't make
> > sense.
> >
> >
> > On Tue, Nov 16, 2021 at 6:14 PM Lon Varscsak <lo...@gmail.com>
> wrote:
> >
> >> I forgot to mention that I'm running 4.2.M4-SNAPSHOT (updated from
> github
> >> as of an hour ago).
> >>
> >> On Tue, Nov 16, 2021 at 4:06 PM Lon Varscsak <lo...@gmail.com>
> >> wrote:
> >>
> >>> Hey all,
> >>>
> >>> I have a setup where I have an optional to-one relationship, but when I
> >>> try to clear the relationship and commitChanges, I get a low-level
> >> Cayenne
> >>> error along with some in appropriate sql generated.
> >>>
> >>> where it's doing an UPDATE to order_detail_costs should be a no-op,
> >>> because the object was removed from it's parent (order_detail_sales)
> with
> >>> setOrderDetailCost(null) along with a
> >>> objectContext.deleteObject(orderDetailCost).  This is probably a
> problem
> >>> for Nikita to look at, but I figured someone else may have run into
> this
> >> as
> >>> well.  It's unusual for me to have optional to-one relationships, but
> it
> >>> does happen.
> >>>
> >>> Here is a sample project (Debug As -> Java Application) to try (link to
> >> my
> >>> Synology):
> >>>
> >>
> https://varscsak.synology.me:5001/d/s/mI7SBS6fApoUMNT1K5lfpaCXHKEkHkgd/jIy5Ug64Hjp2ieZzOceknc39sjBasJLE-T74gPgqKEgk
> >>>
> >>> ...snip...
> >>>
> >>> Nov 16 15:27:55 INFO  org.apache.cayenne.log.JdbcEventLogger  - INSERT
> >>> INTO "order_header"( "attribute_1", "attribute_2", "order_number")
> >> VALUES(
> >>> ?, ?, ?)
> >>>
> >>> Nov 16 15:27:55 INFO  org.apache.cayenne.log.JdbcEventLogger  - [bind:
> >>> 1->attribute_1:'TEST1', 2->attribute_2:1, 3->order_number:1]
> >>>
> >>> Nov 16 15:27:55 INFO  org.apache.cayenne.log.JdbcEventLogger  - ===
> >>> updated 1 row.
> >>>
> >>> Nov 16 15:27:55 INFO  org.apache.cayenne.log.JdbcEventLogger  - INSERT
> >>> INTO "order_detail_sales"( "detail_attr_1", "detail_attr_2",
> >>> "order_line_number", "order_number") VALUES( ?, ?, ?, ?)
> >>>
> >>> Nov 16 15:27:55 INFO  org.apache.cayenne.log.JdbcEventLogger  - [bind:
> >>> 1->detail_attr_1:'TEST1', 2->detail_attr_2:1, 3->order_line_number:1,
> >>> 4->order_number:1]
> >>>
> >>> Nov 16 15:27:55 INFO  org.apache.cayenne.log.JdbcEventLogger  - ===
> >>> updated 1 row.
> >>>
> >>> Nov 16 15:27:55 INFO  org.apache.cayenne.log.JdbcEventLogger  - UPDATE
> >>> "order_detail_costs" SET "order_number" = ?, "order_line_number" = ?
> >> WHERE
> >>> ( "order_line_number" = ? ) AND ( "order_number" = ? )
> >>>
> >>> Nov 16 15:27:55 INFO  org.apache.cayenne.log.JdbcEventLogger  - ***
> >> error.
> >>>
> >>> java.lang.UnsupportedOperationException
> >>>
> >>> at java.util.Collections$UnmodifiableMap.put(Collections.java:1459)
> >>>
> >>> at
> org.apache.cayenne.query.BatchQueryRow.getValue(BatchQueryRow.java:80)
> >>>
> >>> at org.apache.cayenne.query.UpdateBatchQuery$1.getValue(
> >>> UpdateBatchQuery.java:124)
> >>>
> >>> at
> >>>
> >>
> org.apache.cayenne.access.translator.batch.UpdateBatchTranslator.updateBindings(
> >>> UpdateBatchTranslator.java:80)
> >>>
> >>> at org.apache.cayenne.access.jdbc.BatchAction.runAsIndividualQueries(
> >>> BatchAction.java:191)
> >>>
> >>> at org.apache.cayenne.access.jdbc.BatchAction.performAction(
> >>> BatchAction.java:93)
> >>>
> >>> at org.apache.cayenne.access.DataNodeQueryAction.runQuery(
> >>> DataNodeQueryAction.java:97)
> >>>
> >>> at org.apache.cayenne.access.DataNode.performQueries(DataNode.java:273)
> >>>
> >>> at
> >>>
> >>
> org.apache.cayenne.access.flush.DefaultDataDomainFlushAction.lambda$executeQueries$6(
> >>> DefaultDataDomainFlushAction.java:177)
> >>>
> >>> at java.util.HashMap.forEach(HashMap.java:1290)
> >>>
> >>> at
> >>>
> >>
> org.apache.cayenne.access.flush.DefaultDataDomainFlushAction.executeQueries(
> >>> DefaultDataDomainFlushAction.java:176)
> >>>
> >>> at org.apache.cayenne.access.flush.DefaultDataDomainFlushAction.flush(
> >>> DefaultDataDomainFlushAction.java:89)
> >>>
> >>> at
> org.apache.cayenne.access.DataDomain.onSyncFlush(DataDomain.java:637)
> >>>
> >>> at org.apache.cayenne.access.DataDomain.onSyncNoFilters(
> >>> DataDomain.java:609)
> >>>
> >>> at
> org.apache.cayenne.access.DataDomain$DataDomainSyncFilterChain.onSync(
> >>> DataDomain.java:835)
> >>>
> >>> at org.apache.cayenne.tx.TransactionFilter.lambda$onSync$0(
> >>> TransactionFilter.java:61)
> >>>
> >>> at
> >>>
> >>
> org.apache.cayenne.tx.DefaultTransactionManager$BaseTransactionHandler.performInTransaction(
> >>> DefaultTransactionManager.java:180)
> >>>
> >>> at
> >>>
> >>
> org.apache.cayenne.tx.DefaultTransactionManager$BaseTransactionHandler.performInNewTransaction(
> >>> DefaultTransactionManager.java:152)
> >>>
> >>> at
> >>>
> >>
> org.apache.cayenne.tx.DefaultTransactionManager$NestedTransactionHandler.handle(
> >>> DefaultTransactionManager.java:95)
> >>>
> >>> at
> org.apache.cayenne.tx.DefaultTransactionManager.performInTransaction(
> >>> DefaultTransactionManager.java:62)
> >>>
> >>> at
> org.apache.cayenne.tx.DefaultTransactionManager.performInTransaction(
> >>> DefaultTransactionManager.java:40)
> >>>
> >>> at org.apache.cayenne.tx.TransactionFilter.onSync(
> >>> TransactionFilter.java:61)
> >>>
> >>> at
> org.apache.cayenne.access.DataDomain$DataDomainSyncFilterChain.onSync(
> >>> DataDomain.java:834)
> >>>
> >>> at org.apache.cayenne.access.DataDomain.onSync(DataDomain.java:596)
> >>>
> >>> at org.apache.cayenne.access.DataContext.flushToParent(
> >>> DataContext.java:737)
> >>>
> >>> at org.apache.cayenne.access.DataContext.commitChanges(
> >>> DataContext.java:686)
> >>>
> >>> at com.smarthealth.cayennetest.App.main(App.java:38)
> >>>
> >>> Nov 16 15:27:55 INFO  org.apache.cayenne.log.JdbcEventLogger  - ***
> >>> transaction rolledback.
> >>>
> >>> org.apache.cayenne.CayenneRuntimeException: [v.4.2.M4-SNAPSHOT Nov 16
> >>> 2021 22:12:02] Commit Exception
> >>>
> >>> at org.apache.cayenne.access.DataContext.flushToParent(
> >>> DataContext.java:769)
> >>>
> >>> at org.apache.cayenne.access.DataContext.commitChanges(
> >>> DataContext.java:686)
> >>>
> >>> at com.smarthealth.cayennetest.App.main(App.java:38)
> >>>
> >>> Caused by: java.lang.UnsupportedOperationException
> >>>
> >>> at java.util.Collections$UnmodifiableMap.put(Collections.java:1459)
> >>>
> >>> at
> org.apache.cayenne.query.BatchQueryRow.getValue(BatchQueryRow.java:80)
> >>>
> >>> at org.apache.cayenne.query.UpdateBatchQuery$1.getValue(
> >>> UpdateBatchQuery.java:124)
> >>>
> >>> at
> >>>
> >>
> org.apache.cayenne.access.translator.batch.UpdateBatchTranslator.updateBindings(
> >>> UpdateBatchTranslator.java:80)
> >>>
> >>> at org.apache.cayenne.access.jdbc.BatchAction.runAsIndividualQueries(
> >>> BatchAction.java:191)
> >>>
> >>> at org.apache.cayenne.access.jdbc.BatchAction.performAction(
> >>> BatchAction.java:93)
> >>>
> >>> at org.apache.cayenne.access.DataNodeQueryAction.runQuery(
> >>> DataNodeQueryAction.java:97)
> >>>
> >>> at org.apache.cayenne.access.DataNode.performQueries(DataNode.java:273)
> >>>
> >>> at
> >>>
> >>
> org.apache.cayenne.access.flush.DefaultDataDomainFlushAction.lambda$executeQueries$6(
> >>> DefaultDataDomainFlushAction.java:177)
> >>>
> >>> at java.util.HashMap.forEach(HashMap.java:1290)
> >>>
> >>> at
> >>>
> >>
> org.apache.cayenne.access.flush.DefaultDataDomainFlushAction.executeQueries(
> >>> DefaultDataDomainFlushAction.java:176)
> >>>
> >>> at org.apache.cayenne.access.flush.DefaultDataDomainFlushAction.flush(
> >>> DefaultDataDomainFlushAction.java:89)
> >>>
> >>> at
> org.apache.cayenne.access.DataDomain.onSyncFlush(DataDomain.java:637)
> >>>
> >>> at org.apache.cayenne.access.DataDomain.onSyncNoFilters(
> >>> DataDomain.java:609)
> >>>
> >>> at
> org.apache.cayenne.access.DataDomain$DataDomainSyncFilterChain.onSync(
> >>> DataDomain.java:835)
> >>>
> >>> at org.apache.cayenne.tx.TransactionFilter.lambda$onSync$0(
> >>> TransactionFilter.java:61)
> >>>
> >>> at
> >>>
> >>
> org.apache.cayenne.tx.DefaultTransactionManager$BaseTransactionHandler.performInTransaction(
> >>> DefaultTransactionManager.java:180)
> >>>
> >>> at
> >>>
> >>
> org.apache.cayenne.tx.DefaultTransactionManager$BaseTransactionHandler.performInNewTransaction(
> >>> DefaultTransactionManager.java:152)
> >>>
> >>> at
> >>>
> >>
> org.apache.cayenne.tx.DefaultTransactionManager$NestedTransactionHandler.handle(
> >>> DefaultTransactionManager.java:95)
> >>>
> >>> at
> org.apache.cayenne.tx.DefaultTransactionManager.performInTransaction(
> >>> DefaultTransactionManager.java:62)
> >>>
> >>> at
> org.apache.cayenne.tx.DefaultTransactionManager.performInTransaction(
> >>> DefaultTransactionManager.java:40)
> >>>
> >>> at org.apache.cayenne.tx.TransactionFilter.onSync(
> >>> TransactionFilter.java:61)
> >>>
> >>> at
> org.apache.cayenne.access.DataDomain$DataDomainSyncFilterChain.onSync(
> >>> DataDomain.java:834)
> >>>
> >>> at org.apache.cayenne.access.DataDomain.onSync(DataDomain.java:596)
> >>>
> >>> at org.apache.cayenne.access.DataContext.flushToParent(
> >>> DataContext.java:737)
> >>>
> >>> ... 2 more
> >>>
> >>>
> >>>
> >>
>
>

Re: Problem with optional to-one deletion

Posted by Andrus Adamchik <aa...@gmail.com>.
Hi Mike,

Nikita mentioned a few hours ago that he was able to reproduce. Appears to be a bug in the 4.2 stack.

Andrus

> On Nov 17, 2021, at 7:44 PM, Michael Gentry <bl...@gmail.com> wrote:
> 
> Hi Lon,
> 
> I didn't have a lot of time to look into it, but I suspect it may be in
> your PK/FK mapping on the DbEntities.
> 
> For example, in order_header, you have order_header ->> order_detail_sales,
> but you've mapped that as To-Many AND To-Dependent PK, which doesn't make
> sense.
> 
> 
> On Tue, Nov 16, 2021 at 6:14 PM Lon Varscsak <lo...@gmail.com> wrote:
> 
>> I forgot to mention that I'm running 4.2.M4-SNAPSHOT (updated from github
>> as of an hour ago).
>> 
>> On Tue, Nov 16, 2021 at 4:06 PM Lon Varscsak <lo...@gmail.com>
>> wrote:
>> 
>>> Hey all,
>>> 
>>> I have a setup where I have an optional to-one relationship, but when I
>>> try to clear the relationship and commitChanges, I get a low-level
>> Cayenne
>>> error along with some in appropriate sql generated.
>>> 
>>> where it's doing an UPDATE to order_detail_costs should be a no-op,
>>> because the object was removed from it's parent (order_detail_sales) with
>>> setOrderDetailCost(null) along with a
>>> objectContext.deleteObject(orderDetailCost).  This is probably a problem
>>> for Nikita to look at, but I figured someone else may have run into this
>> as
>>> well.  It's unusual for me to have optional to-one relationships, but it
>>> does happen.
>>> 
>>> Here is a sample project (Debug As -> Java Application) to try (link to
>> my
>>> Synology):
>>> 
>> https://varscsak.synology.me:5001/d/s/mI7SBS6fApoUMNT1K5lfpaCXHKEkHkgd/jIy5Ug64Hjp2ieZzOceknc39sjBasJLE-T74gPgqKEgk
>>> 
>>> ...snip...
>>> 
>>> Nov 16 15:27:55 INFO  org.apache.cayenne.log.JdbcEventLogger  - INSERT
>>> INTO "order_header"( "attribute_1", "attribute_2", "order_number")
>> VALUES(
>>> ?, ?, ?)
>>> 
>>> Nov 16 15:27:55 INFO  org.apache.cayenne.log.JdbcEventLogger  - [bind:
>>> 1->attribute_1:'TEST1', 2->attribute_2:1, 3->order_number:1]
>>> 
>>> Nov 16 15:27:55 INFO  org.apache.cayenne.log.JdbcEventLogger  - ===
>>> updated 1 row.
>>> 
>>> Nov 16 15:27:55 INFO  org.apache.cayenne.log.JdbcEventLogger  - INSERT
>>> INTO "order_detail_sales"( "detail_attr_1", "detail_attr_2",
>>> "order_line_number", "order_number") VALUES( ?, ?, ?, ?)
>>> 
>>> Nov 16 15:27:55 INFO  org.apache.cayenne.log.JdbcEventLogger  - [bind:
>>> 1->detail_attr_1:'TEST1', 2->detail_attr_2:1, 3->order_line_number:1,
>>> 4->order_number:1]
>>> 
>>> Nov 16 15:27:55 INFO  org.apache.cayenne.log.JdbcEventLogger  - ===
>>> updated 1 row.
>>> 
>>> Nov 16 15:27:55 INFO  org.apache.cayenne.log.JdbcEventLogger  - UPDATE
>>> "order_detail_costs" SET "order_number" = ?, "order_line_number" = ?
>> WHERE
>>> ( "order_line_number" = ? ) AND ( "order_number" = ? )
>>> 
>>> Nov 16 15:27:55 INFO  org.apache.cayenne.log.JdbcEventLogger  - ***
>> error.
>>> 
>>> java.lang.UnsupportedOperationException
>>> 
>>> at java.util.Collections$UnmodifiableMap.put(Collections.java:1459)
>>> 
>>> at org.apache.cayenne.query.BatchQueryRow.getValue(BatchQueryRow.java:80)
>>> 
>>> at org.apache.cayenne.query.UpdateBatchQuery$1.getValue(
>>> UpdateBatchQuery.java:124)
>>> 
>>> at
>>> 
>> org.apache.cayenne.access.translator.batch.UpdateBatchTranslator.updateBindings(
>>> UpdateBatchTranslator.java:80)
>>> 
>>> at org.apache.cayenne.access.jdbc.BatchAction.runAsIndividualQueries(
>>> BatchAction.java:191)
>>> 
>>> at org.apache.cayenne.access.jdbc.BatchAction.performAction(
>>> BatchAction.java:93)
>>> 
>>> at org.apache.cayenne.access.DataNodeQueryAction.runQuery(
>>> DataNodeQueryAction.java:97)
>>> 
>>> at org.apache.cayenne.access.DataNode.performQueries(DataNode.java:273)
>>> 
>>> at
>>> 
>> org.apache.cayenne.access.flush.DefaultDataDomainFlushAction.lambda$executeQueries$6(
>>> DefaultDataDomainFlushAction.java:177)
>>> 
>>> at java.util.HashMap.forEach(HashMap.java:1290)
>>> 
>>> at
>>> 
>> org.apache.cayenne.access.flush.DefaultDataDomainFlushAction.executeQueries(
>>> DefaultDataDomainFlushAction.java:176)
>>> 
>>> at org.apache.cayenne.access.flush.DefaultDataDomainFlushAction.flush(
>>> DefaultDataDomainFlushAction.java:89)
>>> 
>>> at org.apache.cayenne.access.DataDomain.onSyncFlush(DataDomain.java:637)
>>> 
>>> at org.apache.cayenne.access.DataDomain.onSyncNoFilters(
>>> DataDomain.java:609)
>>> 
>>> at org.apache.cayenne.access.DataDomain$DataDomainSyncFilterChain.onSync(
>>> DataDomain.java:835)
>>> 
>>> at org.apache.cayenne.tx.TransactionFilter.lambda$onSync$0(
>>> TransactionFilter.java:61)
>>> 
>>> at
>>> 
>> org.apache.cayenne.tx.DefaultTransactionManager$BaseTransactionHandler.performInTransaction(
>>> DefaultTransactionManager.java:180)
>>> 
>>> at
>>> 
>> org.apache.cayenne.tx.DefaultTransactionManager$BaseTransactionHandler.performInNewTransaction(
>>> DefaultTransactionManager.java:152)
>>> 
>>> at
>>> 
>> org.apache.cayenne.tx.DefaultTransactionManager$NestedTransactionHandler.handle(
>>> DefaultTransactionManager.java:95)
>>> 
>>> at org.apache.cayenne.tx.DefaultTransactionManager.performInTransaction(
>>> DefaultTransactionManager.java:62)
>>> 
>>> at org.apache.cayenne.tx.DefaultTransactionManager.performInTransaction(
>>> DefaultTransactionManager.java:40)
>>> 
>>> at org.apache.cayenne.tx.TransactionFilter.onSync(
>>> TransactionFilter.java:61)
>>> 
>>> at org.apache.cayenne.access.DataDomain$DataDomainSyncFilterChain.onSync(
>>> DataDomain.java:834)
>>> 
>>> at org.apache.cayenne.access.DataDomain.onSync(DataDomain.java:596)
>>> 
>>> at org.apache.cayenne.access.DataContext.flushToParent(
>>> DataContext.java:737)
>>> 
>>> at org.apache.cayenne.access.DataContext.commitChanges(
>>> DataContext.java:686)
>>> 
>>> at com.smarthealth.cayennetest.App.main(App.java:38)
>>> 
>>> Nov 16 15:27:55 INFO  org.apache.cayenne.log.JdbcEventLogger  - ***
>>> transaction rolledback.
>>> 
>>> org.apache.cayenne.CayenneRuntimeException: [v.4.2.M4-SNAPSHOT Nov 16
>>> 2021 22:12:02] Commit Exception
>>> 
>>> at org.apache.cayenne.access.DataContext.flushToParent(
>>> DataContext.java:769)
>>> 
>>> at org.apache.cayenne.access.DataContext.commitChanges(
>>> DataContext.java:686)
>>> 
>>> at com.smarthealth.cayennetest.App.main(App.java:38)
>>> 
>>> Caused by: java.lang.UnsupportedOperationException
>>> 
>>> at java.util.Collections$UnmodifiableMap.put(Collections.java:1459)
>>> 
>>> at org.apache.cayenne.query.BatchQueryRow.getValue(BatchQueryRow.java:80)
>>> 
>>> at org.apache.cayenne.query.UpdateBatchQuery$1.getValue(
>>> UpdateBatchQuery.java:124)
>>> 
>>> at
>>> 
>> org.apache.cayenne.access.translator.batch.UpdateBatchTranslator.updateBindings(
>>> UpdateBatchTranslator.java:80)
>>> 
>>> at org.apache.cayenne.access.jdbc.BatchAction.runAsIndividualQueries(
>>> BatchAction.java:191)
>>> 
>>> at org.apache.cayenne.access.jdbc.BatchAction.performAction(
>>> BatchAction.java:93)
>>> 
>>> at org.apache.cayenne.access.DataNodeQueryAction.runQuery(
>>> DataNodeQueryAction.java:97)
>>> 
>>> at org.apache.cayenne.access.DataNode.performQueries(DataNode.java:273)
>>> 
>>> at
>>> 
>> org.apache.cayenne.access.flush.DefaultDataDomainFlushAction.lambda$executeQueries$6(
>>> DefaultDataDomainFlushAction.java:177)
>>> 
>>> at java.util.HashMap.forEach(HashMap.java:1290)
>>> 
>>> at
>>> 
>> org.apache.cayenne.access.flush.DefaultDataDomainFlushAction.executeQueries(
>>> DefaultDataDomainFlushAction.java:176)
>>> 
>>> at org.apache.cayenne.access.flush.DefaultDataDomainFlushAction.flush(
>>> DefaultDataDomainFlushAction.java:89)
>>> 
>>> at org.apache.cayenne.access.DataDomain.onSyncFlush(DataDomain.java:637)
>>> 
>>> at org.apache.cayenne.access.DataDomain.onSyncNoFilters(
>>> DataDomain.java:609)
>>> 
>>> at org.apache.cayenne.access.DataDomain$DataDomainSyncFilterChain.onSync(
>>> DataDomain.java:835)
>>> 
>>> at org.apache.cayenne.tx.TransactionFilter.lambda$onSync$0(
>>> TransactionFilter.java:61)
>>> 
>>> at
>>> 
>> org.apache.cayenne.tx.DefaultTransactionManager$BaseTransactionHandler.performInTransaction(
>>> DefaultTransactionManager.java:180)
>>> 
>>> at
>>> 
>> org.apache.cayenne.tx.DefaultTransactionManager$BaseTransactionHandler.performInNewTransaction(
>>> DefaultTransactionManager.java:152)
>>> 
>>> at
>>> 
>> org.apache.cayenne.tx.DefaultTransactionManager$NestedTransactionHandler.handle(
>>> DefaultTransactionManager.java:95)
>>> 
>>> at org.apache.cayenne.tx.DefaultTransactionManager.performInTransaction(
>>> DefaultTransactionManager.java:62)
>>> 
>>> at org.apache.cayenne.tx.DefaultTransactionManager.performInTransaction(
>>> DefaultTransactionManager.java:40)
>>> 
>>> at org.apache.cayenne.tx.TransactionFilter.onSync(
>>> TransactionFilter.java:61)
>>> 
>>> at org.apache.cayenne.access.DataDomain$DataDomainSyncFilterChain.onSync(
>>> DataDomain.java:834)
>>> 
>>> at org.apache.cayenne.access.DataDomain.onSync(DataDomain.java:596)
>>> 
>>> at org.apache.cayenne.access.DataContext.flushToParent(
>>> DataContext.java:737)
>>> 
>>> ... 2 more
>>> 
>>> 
>>> 
>> 


Re: Problem with optional to-one deletion

Posted by Michael Gentry <bl...@gmail.com>.
Hi Lon,

I didn't have a lot of time to look into it, but I suspect it may be in
your PK/FK mapping on the DbEntities.

For example, in order_header, you have order_header ->> order_detail_sales,
but you've mapped that as To-Many AND To-Dependent PK, which doesn't make
sense.


On Tue, Nov 16, 2021 at 6:14 PM Lon Varscsak <lo...@gmail.com> wrote:

> I forgot to mention that I'm running 4.2.M4-SNAPSHOT (updated from github
> as of an hour ago).
>
> On Tue, Nov 16, 2021 at 4:06 PM Lon Varscsak <lo...@gmail.com>
> wrote:
>
> > Hey all,
> >
> > I have a setup where I have an optional to-one relationship, but when I
> > try to clear the relationship and commitChanges, I get a low-level
> Cayenne
> > error along with some in appropriate sql generated.
> >
> > where it's doing an UPDATE to order_detail_costs should be a no-op,
> > because the object was removed from it's parent (order_detail_sales) with
> > setOrderDetailCost(null) along with a
> > objectContext.deleteObject(orderDetailCost).  This is probably a problem
> > for Nikita to look at, but I figured someone else may have run into this
> as
> > well.  It's unusual for me to have optional to-one relationships, but it
> > does happen.
> >
> > Here is a sample project (Debug As -> Java Application) to try (link to
> my
> > Synology):
> >
> https://varscsak.synology.me:5001/d/s/mI7SBS6fApoUMNT1K5lfpaCXHKEkHkgd/jIy5Ug64Hjp2ieZzOceknc39sjBasJLE-T74gPgqKEgk
> >
> > ...snip...
> >
> > Nov 16 15:27:55 INFO  org.apache.cayenne.log.JdbcEventLogger  - INSERT
> > INTO "order_header"( "attribute_1", "attribute_2", "order_number")
> VALUES(
> > ?, ?, ?)
> >
> > Nov 16 15:27:55 INFO  org.apache.cayenne.log.JdbcEventLogger  - [bind:
> > 1->attribute_1:'TEST1', 2->attribute_2:1, 3->order_number:1]
> >
> > Nov 16 15:27:55 INFO  org.apache.cayenne.log.JdbcEventLogger  - ===
> > updated 1 row.
> >
> > Nov 16 15:27:55 INFO  org.apache.cayenne.log.JdbcEventLogger  - INSERT
> > INTO "order_detail_sales"( "detail_attr_1", "detail_attr_2",
> > "order_line_number", "order_number") VALUES( ?, ?, ?, ?)
> >
> > Nov 16 15:27:55 INFO  org.apache.cayenne.log.JdbcEventLogger  - [bind:
> > 1->detail_attr_1:'TEST1', 2->detail_attr_2:1, 3->order_line_number:1,
> > 4->order_number:1]
> >
> > Nov 16 15:27:55 INFO  org.apache.cayenne.log.JdbcEventLogger  - ===
> > updated 1 row.
> >
> > Nov 16 15:27:55 INFO  org.apache.cayenne.log.JdbcEventLogger  - UPDATE
> > "order_detail_costs" SET "order_number" = ?, "order_line_number" = ?
> WHERE
> > ( "order_line_number" = ? ) AND ( "order_number" = ? )
> >
> > Nov 16 15:27:55 INFO  org.apache.cayenne.log.JdbcEventLogger  - ***
> error.
> >
> > java.lang.UnsupportedOperationException
> >
> > at java.util.Collections$UnmodifiableMap.put(Collections.java:1459)
> >
> > at org.apache.cayenne.query.BatchQueryRow.getValue(BatchQueryRow.java:80)
> >
> > at org.apache.cayenne.query.UpdateBatchQuery$1.getValue(
> > UpdateBatchQuery.java:124)
> >
> > at
> >
> org.apache.cayenne.access.translator.batch.UpdateBatchTranslator.updateBindings(
> > UpdateBatchTranslator.java:80)
> >
> > at org.apache.cayenne.access.jdbc.BatchAction.runAsIndividualQueries(
> > BatchAction.java:191)
> >
> > at org.apache.cayenne.access.jdbc.BatchAction.performAction(
> > BatchAction.java:93)
> >
> > at org.apache.cayenne.access.DataNodeQueryAction.runQuery(
> > DataNodeQueryAction.java:97)
> >
> > at org.apache.cayenne.access.DataNode.performQueries(DataNode.java:273)
> >
> > at
> >
> org.apache.cayenne.access.flush.DefaultDataDomainFlushAction.lambda$executeQueries$6(
> > DefaultDataDomainFlushAction.java:177)
> >
> > at java.util.HashMap.forEach(HashMap.java:1290)
> >
> > at
> >
> org.apache.cayenne.access.flush.DefaultDataDomainFlushAction.executeQueries(
> > DefaultDataDomainFlushAction.java:176)
> >
> > at org.apache.cayenne.access.flush.DefaultDataDomainFlushAction.flush(
> > DefaultDataDomainFlushAction.java:89)
> >
> > at org.apache.cayenne.access.DataDomain.onSyncFlush(DataDomain.java:637)
> >
> > at org.apache.cayenne.access.DataDomain.onSyncNoFilters(
> > DataDomain.java:609)
> >
> > at org.apache.cayenne.access.DataDomain$DataDomainSyncFilterChain.onSync(
> > DataDomain.java:835)
> >
> > at org.apache.cayenne.tx.TransactionFilter.lambda$onSync$0(
> > TransactionFilter.java:61)
> >
> > at
> >
> org.apache.cayenne.tx.DefaultTransactionManager$BaseTransactionHandler.performInTransaction(
> > DefaultTransactionManager.java:180)
> >
> > at
> >
> org.apache.cayenne.tx.DefaultTransactionManager$BaseTransactionHandler.performInNewTransaction(
> > DefaultTransactionManager.java:152)
> >
> > at
> >
> org.apache.cayenne.tx.DefaultTransactionManager$NestedTransactionHandler.handle(
> > DefaultTransactionManager.java:95)
> >
> > at org.apache.cayenne.tx.DefaultTransactionManager.performInTransaction(
> > DefaultTransactionManager.java:62)
> >
> > at org.apache.cayenne.tx.DefaultTransactionManager.performInTransaction(
> > DefaultTransactionManager.java:40)
> >
> > at org.apache.cayenne.tx.TransactionFilter.onSync(
> > TransactionFilter.java:61)
> >
> > at org.apache.cayenne.access.DataDomain$DataDomainSyncFilterChain.onSync(
> > DataDomain.java:834)
> >
> > at org.apache.cayenne.access.DataDomain.onSync(DataDomain.java:596)
> >
> > at org.apache.cayenne.access.DataContext.flushToParent(
> > DataContext.java:737)
> >
> > at org.apache.cayenne.access.DataContext.commitChanges(
> > DataContext.java:686)
> >
> > at com.smarthealth.cayennetest.App.main(App.java:38)
> >
> > Nov 16 15:27:55 INFO  org.apache.cayenne.log.JdbcEventLogger  - ***
> > transaction rolledback.
> >
> > org.apache.cayenne.CayenneRuntimeException: [v.4.2.M4-SNAPSHOT Nov 16
> > 2021 22:12:02] Commit Exception
> >
> > at org.apache.cayenne.access.DataContext.flushToParent(
> > DataContext.java:769)
> >
> > at org.apache.cayenne.access.DataContext.commitChanges(
> > DataContext.java:686)
> >
> > at com.smarthealth.cayennetest.App.main(App.java:38)
> >
> > Caused by: java.lang.UnsupportedOperationException
> >
> > at java.util.Collections$UnmodifiableMap.put(Collections.java:1459)
> >
> > at org.apache.cayenne.query.BatchQueryRow.getValue(BatchQueryRow.java:80)
> >
> > at org.apache.cayenne.query.UpdateBatchQuery$1.getValue(
> > UpdateBatchQuery.java:124)
> >
> > at
> >
> org.apache.cayenne.access.translator.batch.UpdateBatchTranslator.updateBindings(
> > UpdateBatchTranslator.java:80)
> >
> > at org.apache.cayenne.access.jdbc.BatchAction.runAsIndividualQueries(
> > BatchAction.java:191)
> >
> > at org.apache.cayenne.access.jdbc.BatchAction.performAction(
> > BatchAction.java:93)
> >
> > at org.apache.cayenne.access.DataNodeQueryAction.runQuery(
> > DataNodeQueryAction.java:97)
> >
> > at org.apache.cayenne.access.DataNode.performQueries(DataNode.java:273)
> >
> > at
> >
> org.apache.cayenne.access.flush.DefaultDataDomainFlushAction.lambda$executeQueries$6(
> > DefaultDataDomainFlushAction.java:177)
> >
> > at java.util.HashMap.forEach(HashMap.java:1290)
> >
> > at
> >
> org.apache.cayenne.access.flush.DefaultDataDomainFlushAction.executeQueries(
> > DefaultDataDomainFlushAction.java:176)
> >
> > at org.apache.cayenne.access.flush.DefaultDataDomainFlushAction.flush(
> > DefaultDataDomainFlushAction.java:89)
> >
> > at org.apache.cayenne.access.DataDomain.onSyncFlush(DataDomain.java:637)
> >
> > at org.apache.cayenne.access.DataDomain.onSyncNoFilters(
> > DataDomain.java:609)
> >
> > at org.apache.cayenne.access.DataDomain$DataDomainSyncFilterChain.onSync(
> > DataDomain.java:835)
> >
> > at org.apache.cayenne.tx.TransactionFilter.lambda$onSync$0(
> > TransactionFilter.java:61)
> >
> > at
> >
> org.apache.cayenne.tx.DefaultTransactionManager$BaseTransactionHandler.performInTransaction(
> > DefaultTransactionManager.java:180)
> >
> > at
> >
> org.apache.cayenne.tx.DefaultTransactionManager$BaseTransactionHandler.performInNewTransaction(
> > DefaultTransactionManager.java:152)
> >
> > at
> >
> org.apache.cayenne.tx.DefaultTransactionManager$NestedTransactionHandler.handle(
> > DefaultTransactionManager.java:95)
> >
> > at org.apache.cayenne.tx.DefaultTransactionManager.performInTransaction(
> > DefaultTransactionManager.java:62)
> >
> > at org.apache.cayenne.tx.DefaultTransactionManager.performInTransaction(
> > DefaultTransactionManager.java:40)
> >
> > at org.apache.cayenne.tx.TransactionFilter.onSync(
> > TransactionFilter.java:61)
> >
> > at org.apache.cayenne.access.DataDomain$DataDomainSyncFilterChain.onSync(
> > DataDomain.java:834)
> >
> > at org.apache.cayenne.access.DataDomain.onSync(DataDomain.java:596)
> >
> > at org.apache.cayenne.access.DataContext.flushToParent(
> > DataContext.java:737)
> >
> > ... 2 more
> >
> >
> >
>

Re: Problem with optional to-one deletion

Posted by Lon Varscsak <lo...@gmail.com>.
I forgot to mention that I'm running 4.2.M4-SNAPSHOT (updated from github
as of an hour ago).

On Tue, Nov 16, 2021 at 4:06 PM Lon Varscsak <lo...@gmail.com> wrote:

> Hey all,
>
> I have a setup where I have an optional to-one relationship, but when I
> try to clear the relationship and commitChanges, I get a low-level Cayenne
> error along with some in appropriate sql generated.
>
> where it's doing an UPDATE to order_detail_costs should be a no-op,
> because the object was removed from it's parent (order_detail_sales) with
> setOrderDetailCost(null) along with a
> objectContext.deleteObject(orderDetailCost).  This is probably a problem
> for Nikita to look at, but I figured someone else may have run into this as
> well.  It's unusual for me to have optional to-one relationships, but it
> does happen.
>
> Here is a sample project (Debug As -> Java Application) to try (link to my
> Synology):
> https://varscsak.synology.me:5001/d/s/mI7SBS6fApoUMNT1K5lfpaCXHKEkHkgd/jIy5Ug64Hjp2ieZzOceknc39sjBasJLE-T74gPgqKEgk
>
> ...snip...
>
> Nov 16 15:27:55 INFO  org.apache.cayenne.log.JdbcEventLogger  - INSERT
> INTO "order_header"( "attribute_1", "attribute_2", "order_number") VALUES(
> ?, ?, ?)
>
> Nov 16 15:27:55 INFO  org.apache.cayenne.log.JdbcEventLogger  - [bind:
> 1->attribute_1:'TEST1', 2->attribute_2:1, 3->order_number:1]
>
> Nov 16 15:27:55 INFO  org.apache.cayenne.log.JdbcEventLogger  - ===
> updated 1 row.
>
> Nov 16 15:27:55 INFO  org.apache.cayenne.log.JdbcEventLogger  - INSERT
> INTO "order_detail_sales"( "detail_attr_1", "detail_attr_2",
> "order_line_number", "order_number") VALUES( ?, ?, ?, ?)
>
> Nov 16 15:27:55 INFO  org.apache.cayenne.log.JdbcEventLogger  - [bind:
> 1->detail_attr_1:'TEST1', 2->detail_attr_2:1, 3->order_line_number:1,
> 4->order_number:1]
>
> Nov 16 15:27:55 INFO  org.apache.cayenne.log.JdbcEventLogger  - ===
> updated 1 row.
>
> Nov 16 15:27:55 INFO  org.apache.cayenne.log.JdbcEventLogger  - UPDATE
> "order_detail_costs" SET "order_number" = ?, "order_line_number" = ? WHERE
> ( "order_line_number" = ? ) AND ( "order_number" = ? )
>
> Nov 16 15:27:55 INFO  org.apache.cayenne.log.JdbcEventLogger  - *** error.
>
> java.lang.UnsupportedOperationException
>
> at java.util.Collections$UnmodifiableMap.put(Collections.java:1459)
>
> at org.apache.cayenne.query.BatchQueryRow.getValue(BatchQueryRow.java:80)
>
> at org.apache.cayenne.query.UpdateBatchQuery$1.getValue(
> UpdateBatchQuery.java:124)
>
> at
> org.apache.cayenne.access.translator.batch.UpdateBatchTranslator.updateBindings(
> UpdateBatchTranslator.java:80)
>
> at org.apache.cayenne.access.jdbc.BatchAction.runAsIndividualQueries(
> BatchAction.java:191)
>
> at org.apache.cayenne.access.jdbc.BatchAction.performAction(
> BatchAction.java:93)
>
> at org.apache.cayenne.access.DataNodeQueryAction.runQuery(
> DataNodeQueryAction.java:97)
>
> at org.apache.cayenne.access.DataNode.performQueries(DataNode.java:273)
>
> at
> org.apache.cayenne.access.flush.DefaultDataDomainFlushAction.lambda$executeQueries$6(
> DefaultDataDomainFlushAction.java:177)
>
> at java.util.HashMap.forEach(HashMap.java:1290)
>
> at
> org.apache.cayenne.access.flush.DefaultDataDomainFlushAction.executeQueries(
> DefaultDataDomainFlushAction.java:176)
>
> at org.apache.cayenne.access.flush.DefaultDataDomainFlushAction.flush(
> DefaultDataDomainFlushAction.java:89)
>
> at org.apache.cayenne.access.DataDomain.onSyncFlush(DataDomain.java:637)
>
> at org.apache.cayenne.access.DataDomain.onSyncNoFilters(
> DataDomain.java:609)
>
> at org.apache.cayenne.access.DataDomain$DataDomainSyncFilterChain.onSync(
> DataDomain.java:835)
>
> at org.apache.cayenne.tx.TransactionFilter.lambda$onSync$0(
> TransactionFilter.java:61)
>
> at
> org.apache.cayenne.tx.DefaultTransactionManager$BaseTransactionHandler.performInTransaction(
> DefaultTransactionManager.java:180)
>
> at
> org.apache.cayenne.tx.DefaultTransactionManager$BaseTransactionHandler.performInNewTransaction(
> DefaultTransactionManager.java:152)
>
> at
> org.apache.cayenne.tx.DefaultTransactionManager$NestedTransactionHandler.handle(
> DefaultTransactionManager.java:95)
>
> at org.apache.cayenne.tx.DefaultTransactionManager.performInTransaction(
> DefaultTransactionManager.java:62)
>
> at org.apache.cayenne.tx.DefaultTransactionManager.performInTransaction(
> DefaultTransactionManager.java:40)
>
> at org.apache.cayenne.tx.TransactionFilter.onSync(
> TransactionFilter.java:61)
>
> at org.apache.cayenne.access.DataDomain$DataDomainSyncFilterChain.onSync(
> DataDomain.java:834)
>
> at org.apache.cayenne.access.DataDomain.onSync(DataDomain.java:596)
>
> at org.apache.cayenne.access.DataContext.flushToParent(
> DataContext.java:737)
>
> at org.apache.cayenne.access.DataContext.commitChanges(
> DataContext.java:686)
>
> at com.smarthealth.cayennetest.App.main(App.java:38)
>
> Nov 16 15:27:55 INFO  org.apache.cayenne.log.JdbcEventLogger  - ***
> transaction rolledback.
>
> org.apache.cayenne.CayenneRuntimeException: [v.4.2.M4-SNAPSHOT Nov 16
> 2021 22:12:02] Commit Exception
>
> at org.apache.cayenne.access.DataContext.flushToParent(
> DataContext.java:769)
>
> at org.apache.cayenne.access.DataContext.commitChanges(
> DataContext.java:686)
>
> at com.smarthealth.cayennetest.App.main(App.java:38)
>
> Caused by: java.lang.UnsupportedOperationException
>
> at java.util.Collections$UnmodifiableMap.put(Collections.java:1459)
>
> at org.apache.cayenne.query.BatchQueryRow.getValue(BatchQueryRow.java:80)
>
> at org.apache.cayenne.query.UpdateBatchQuery$1.getValue(
> UpdateBatchQuery.java:124)
>
> at
> org.apache.cayenne.access.translator.batch.UpdateBatchTranslator.updateBindings(
> UpdateBatchTranslator.java:80)
>
> at org.apache.cayenne.access.jdbc.BatchAction.runAsIndividualQueries(
> BatchAction.java:191)
>
> at org.apache.cayenne.access.jdbc.BatchAction.performAction(
> BatchAction.java:93)
>
> at org.apache.cayenne.access.DataNodeQueryAction.runQuery(
> DataNodeQueryAction.java:97)
>
> at org.apache.cayenne.access.DataNode.performQueries(DataNode.java:273)
>
> at
> org.apache.cayenne.access.flush.DefaultDataDomainFlushAction.lambda$executeQueries$6(
> DefaultDataDomainFlushAction.java:177)
>
> at java.util.HashMap.forEach(HashMap.java:1290)
>
> at
> org.apache.cayenne.access.flush.DefaultDataDomainFlushAction.executeQueries(
> DefaultDataDomainFlushAction.java:176)
>
> at org.apache.cayenne.access.flush.DefaultDataDomainFlushAction.flush(
> DefaultDataDomainFlushAction.java:89)
>
> at org.apache.cayenne.access.DataDomain.onSyncFlush(DataDomain.java:637)
>
> at org.apache.cayenne.access.DataDomain.onSyncNoFilters(
> DataDomain.java:609)
>
> at org.apache.cayenne.access.DataDomain$DataDomainSyncFilterChain.onSync(
> DataDomain.java:835)
>
> at org.apache.cayenne.tx.TransactionFilter.lambda$onSync$0(
> TransactionFilter.java:61)
>
> at
> org.apache.cayenne.tx.DefaultTransactionManager$BaseTransactionHandler.performInTransaction(
> DefaultTransactionManager.java:180)
>
> at
> org.apache.cayenne.tx.DefaultTransactionManager$BaseTransactionHandler.performInNewTransaction(
> DefaultTransactionManager.java:152)
>
> at
> org.apache.cayenne.tx.DefaultTransactionManager$NestedTransactionHandler.handle(
> DefaultTransactionManager.java:95)
>
> at org.apache.cayenne.tx.DefaultTransactionManager.performInTransaction(
> DefaultTransactionManager.java:62)
>
> at org.apache.cayenne.tx.DefaultTransactionManager.performInTransaction(
> DefaultTransactionManager.java:40)
>
> at org.apache.cayenne.tx.TransactionFilter.onSync(
> TransactionFilter.java:61)
>
> at org.apache.cayenne.access.DataDomain$DataDomainSyncFilterChain.onSync(
> DataDomain.java:834)
>
> at org.apache.cayenne.access.DataDomain.onSync(DataDomain.java:596)
>
> at org.apache.cayenne.access.DataContext.flushToParent(
> DataContext.java:737)
>
> ... 2 more
>
>
>