[ 
https://issues.apache.org/jira/browse/CAY-2726?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
 ]

Andrus Adamchik updated CAY-2726:
---------------------------------
    Description: 
While we are not handling dependency cycles well during commit operation 
ordering, in some cases Cayenne would exhibit a rather confusing behavior, 
preventing a user from identifying the real problem. 

Here is a perfect self-contained (Docker-based) test case to reproduce: 
https://git.rzen.dev/rzen/cayenne-bigint-test

E1 depends on E2 which depends on E1. When run in a "failure" mode, the 
following warning is printed in the logs, and an unrelated error is thrown. A 
commit between objects creation and establishing a relationship between them 
fixes the issue.

Wonder if we can detect the cycles better? Ultimately Cayenne itself should 
create the steps to overcome the issue (maybe in 5.0), but at the minimum it 
should not try to use "IdGenerationMarker" as a column value, and throw a more 
explicit exception.

{noformat}
[06/Jan/2022:13:05:15,430] main  WARN  o.a.c.a.t.SerializableTypeFactory: 
Haven't found suitable ExtendedType for class 
'org.apache.cayenne.access.flush.IdGenerationMarker'. Most likely you need to 
define a custom ExtendedType.
[06/Jan/2022:13:05:15,430] main  WARN  o.a.c.a.t.SerializableTypeFactory: 
SerializableType will be used for type conversion.
[06/Jan/2022:13:05:15,431] main  INFO  o.a.c.l.JdbcEventLogger: [bind: 
1->e1_id:org.apache.cayenne.access.flush.IdGenerationMarker@9b5c8e3e, 
2->text:'e2 #0']
[06/Jan/2022:13:05:15,439] main  INFO  o.a.c.l.JdbcEventLogger: *** error.
java.sql.SQLException: Cannot convert class [B to SQL type requested due to 
com.mysql.cj.exceptions.WrongArgumentException - Conversion from [B to BIGINT 
is not supported.
        at 
com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:129)
        at 
com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:97)
        at 
com.mysql.cj.jdbc.exceptions.SQLExceptionsMapping.translateException(SQLExceptionsMapping.java:122)
        at 
com.mysql.cj.jdbc.ClientPreparedStatement.setObject(ClientPreparedStatement.java:1684)
        at 
com.zaxxer.hikari.pool.HikariProxyPreparedStatement.setObject(HikariProxyPreparedStatement.java)
        at 
org.apache.cayenne.access.types.ByteArrayType.setJdbcObject(ByteArrayType.java:157)
        at 
org.apache.cayenne.access.types.ByteArrayType.setJdbcObject(ByteArrayType.java:40)
        at 
org.apache.cayenne.access.types.ExtendedTypeDecorator.setJdbcObject(ExtendedTypeDecorator.java:63)
        at 
org.apache.cayenne.dba.JdbcAdapter.bindParameter(JdbcAdapter.java:566)
        at 
org.apache.cayenne.dba.mysql.MySQLAdapter.bindParameter(MySQLAdapter.java:233)
        at 
org.apache.cayenne.dba.AutoAdapter.bindParameter(AutoAdapter.java:222)
        at org.apache.cayenne.access.jdbc.BatchAction.bind(BatchAction.java:62)
        at 
org.apache.cayenne.access.jdbc.BatchAction.runAsIndividualQueries(BatchAction.java:194)
        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.base/java.util.HashMap.forEach(HashMap.java:1337)
        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 test.TestCase.runTest(TestCase.java:27)
{noformat} 

  was:
While we are not handling dependency cycles well during commit operation 
ordering, in some cases Cayenne would display a very confusing behavior, 
preventing a user from identifying the real problem. 

Here is a perfect self-contained (Docker-based) test case to reproduce: 
https://git.rzen.dev/rzen/cayenne-bigint-test

E1 depends on E2 which depends on E1. When run in a "failure" mode, the 
following warning is printed in the logs, and an unrelated error is thrown. 
Doing a commit between object creation and establishing a relationship between 
them fixes the issue.

Wonder if we can detect the cycles better? Ultimately Cayenne itself should 
create the steps to overcome the issue (maybe in 5.0), but at the minimum it 
should no try to use "IdGenerationMarker" as a column value, and throw a more 
explicit exception.

{noformat}
[06/Jan/2022:13:05:15,430] main  WARN  o.a.c.a.t.SerializableTypeFactory: 
Haven't found suitable ExtendedType for class 
'org.apache.cayenne.access.flush.IdGenerationMarker'. Most likely you need to 
define a custom ExtendedType.
[06/Jan/2022:13:05:15,430] main  WARN  o.a.c.a.t.SerializableTypeFactory: 
SerializableType will be used for type conversion.
[06/Jan/2022:13:05:15,431] main  INFO  o.a.c.l.JdbcEventLogger: [bind: 
1->e1_id:org.apache.cayenne.access.flush.IdGenerationMarker@9b5c8e3e, 
2->text:'e2 #0']
[06/Jan/2022:13:05:15,439] main  INFO  o.a.c.l.JdbcEventLogger: *** error.
java.sql.SQLException: Cannot convert class [B to SQL type requested due to 
com.mysql.cj.exceptions.WrongArgumentException - Conversion from [B to BIGINT 
is not supported.
        at 
com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:129)
        at 
com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:97)
        at 
com.mysql.cj.jdbc.exceptions.SQLExceptionsMapping.translateException(SQLExceptionsMapping.java:122)
        at 
com.mysql.cj.jdbc.ClientPreparedStatement.setObject(ClientPreparedStatement.java:1684)
        at 
com.zaxxer.hikari.pool.HikariProxyPreparedStatement.setObject(HikariProxyPreparedStatement.java)
        at 
org.apache.cayenne.access.types.ByteArrayType.setJdbcObject(ByteArrayType.java:157)
        at 
org.apache.cayenne.access.types.ByteArrayType.setJdbcObject(ByteArrayType.java:40)
        at 
org.apache.cayenne.access.types.ExtendedTypeDecorator.setJdbcObject(ExtendedTypeDecorator.java:63)
        at 
org.apache.cayenne.dba.JdbcAdapter.bindParameter(JdbcAdapter.java:566)
        at 
org.apache.cayenne.dba.mysql.MySQLAdapter.bindParameter(MySQLAdapter.java:233)
        at 
org.apache.cayenne.dba.AutoAdapter.bindParameter(AutoAdapter.java:222)
        at org.apache.cayenne.access.jdbc.BatchAction.bind(BatchAction.java:62)
        at 
org.apache.cayenne.access.jdbc.BatchAction.runAsIndividualQueries(BatchAction.java:194)
        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.base/java.util.HashMap.forEach(HashMap.java:1337)
        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 test.TestCase.runTest(TestCase.java:27)
{noformat} 


> Confusing error message on commit of mutually dependent entities
> ----------------------------------------------------------------
>
>                 Key: CAY-2726
>                 URL: https://issues.apache.org/jira/browse/CAY-2726
>             Project: Cayenne
>          Issue Type: Bug
>    Affects Versions: 4.2.B1
>            Reporter: Andrus Adamchik
>            Assignee: Nikita Timofeev
>            Priority: Minor
>             Fix For: 4.2.B2
>
>
> While we are not handling dependency cycles well during commit operation 
> ordering, in some cases Cayenne would exhibit a rather confusing behavior, 
> preventing a user from identifying the real problem. 
> Here is a perfect self-contained (Docker-based) test case to reproduce: 
> https://git.rzen.dev/rzen/cayenne-bigint-test
> E1 depends on E2 which depends on E1. When run in a "failure" mode, the 
> following warning is printed in the logs, and an unrelated error is thrown. A 
> commit between objects creation and establishing a relationship between them 
> fixes the issue.
> Wonder if we can detect the cycles better? Ultimately Cayenne itself should 
> create the steps to overcome the issue (maybe in 5.0), but at the minimum it 
> should not try to use "IdGenerationMarker" as a column value, and throw a 
> more explicit exception.
> {noformat}
> [06/Jan/2022:13:05:15,430] main  WARN  o.a.c.a.t.SerializableTypeFactory: 
> Haven't found suitable ExtendedType for class 
> 'org.apache.cayenne.access.flush.IdGenerationMarker'. Most likely you need to 
> define a custom ExtendedType.
> [06/Jan/2022:13:05:15,430] main  WARN  o.a.c.a.t.SerializableTypeFactory: 
> SerializableType will be used for type conversion.
> [06/Jan/2022:13:05:15,431] main  INFO  o.a.c.l.JdbcEventLogger: [bind: 
> 1->e1_id:org.apache.cayenne.access.flush.IdGenerationMarker@9b5c8e3e, 
> 2->text:'e2 #0']
> [06/Jan/2022:13:05:15,439] main  INFO  o.a.c.l.JdbcEventLogger: *** error.
> java.sql.SQLException: Cannot convert class [B to SQL type requested due to 
> com.mysql.cj.exceptions.WrongArgumentException - Conversion from [B to BIGINT 
> is not supported.
>       at 
> com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:129)
>       at 
> com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:97)
>       at 
> com.mysql.cj.jdbc.exceptions.SQLExceptionsMapping.translateException(SQLExceptionsMapping.java:122)
>       at 
> com.mysql.cj.jdbc.ClientPreparedStatement.setObject(ClientPreparedStatement.java:1684)
>       at 
> com.zaxxer.hikari.pool.HikariProxyPreparedStatement.setObject(HikariProxyPreparedStatement.java)
>       at 
> org.apache.cayenne.access.types.ByteArrayType.setJdbcObject(ByteArrayType.java:157)
>       at 
> org.apache.cayenne.access.types.ByteArrayType.setJdbcObject(ByteArrayType.java:40)
>       at 
> org.apache.cayenne.access.types.ExtendedTypeDecorator.setJdbcObject(ExtendedTypeDecorator.java:63)
>       at 
> org.apache.cayenne.dba.JdbcAdapter.bindParameter(JdbcAdapter.java:566)
>       at 
> org.apache.cayenne.dba.mysql.MySQLAdapter.bindParameter(MySQLAdapter.java:233)
>       at 
> org.apache.cayenne.dba.AutoAdapter.bindParameter(AutoAdapter.java:222)
>       at org.apache.cayenne.access.jdbc.BatchAction.bind(BatchAction.java:62)
>       at 
> org.apache.cayenne.access.jdbc.BatchAction.runAsIndividualQueries(BatchAction.java:194)
>       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.base/java.util.HashMap.forEach(HashMap.java:1337)
>       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 test.TestCase.runTest(TestCase.java:27)
> {noformat} 



--
This message was sent by Atlassian Jira
(v8.20.1#820001)

Reply via email to