[
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)