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

Adam Saghy updated FINERACT-1946:
---------------------------------
    Description: 
Due to the nature of JPA specification the order of the persistence of the 
managed entities are not defined.

When multiple entities are reverse-replayed the new entities will be persisted 
not in a defined order hence the IDENTITY primary key generation:
"{_}Since the provider needs to get the generated ID after each {{{}INSERT{}}}, 
it splits the batch operation to single {{INSERT}} operators and fetches the 
generated ID value after each execution. We just cannot send a batch of 
{{{}INSERT statements and get a batch of generated IDs because we won’t be able 
to associate generated IDs to JPA objects reliably. The reason is that database 
does not guarantee that the order of the generated IDs will be the same as the 
order of INSERTS{}}}. Moreover, {{INSERT}} statements may not be executed in 
the same order as in the batch. So, the only reliable way to get IDs for 
inserted records – split the batch.{_}" 
source: [https://jpa-buddy.com/blog/the-ultimate-guide-on-db-generated/]

Since the loan transactions are ordered primarily based on transaction id and 
secondarily based on the primary key if multiple transactions with the same 
transaction date got reverse-replayed the order of the transactions might be 
changed and hence not consistent.

This could be a major problem, however it can be considered as an edge case in 
most situations.
h3. Solution

*Step 1* - Ordering should be based on {{transaction date}} + {{creation date}} 
+ {{ID}} in this order (For years mysql was used with second precision. That 
implies keeping the ID in the ordering sequence.)

*Step 2* - Set precision of 6 for DATETIME / TIMESTAMP for Mysql / MariaDB 
(PostgresDB is not effected, by default it is using precision of 6 digits after 
seconds)

*It should not cause any backward compatibility issues by default, but having 
more precision we can rely on the ordering by creation date time for the same 
day transactions!*

*Moreover, the* {{LoanTransactionComparator}} *was using* {{creation date 
time}} *as the secondary ordering attribute since 2015!*

*Acceptance criteria*
 * The order of the transactions shall be consistent after the reverse-replaying
 * The order of the reverse-replayed transactions shall match with the original 
order

  was:
Due to the nature of JPA specification the order of the persistence of the 
managed entities are not defined.

When multiple entities are reverse-replayed the new entities will be persisted 
not in a defined order hence the IDENTITY primary key generation:
"{_}Since the provider needs to get the generated ID after each {{{}INSERT{}}}, 
it splits the batch operation to single {{INSERT}} operators and fetches the 
generated ID value after each execution. We just cannot send a batch of 
{{INSERT }}statements and get a batch of generated IDs because we won’t be able 
to associate generated IDs to JPA objects reliably. The reason is that database 
does not guarantee that the order of the generated IDs will be the same as the 
order of {{{}INSERTS{}}}. Moreover, {{INSERT}} statements may not be executed 
in the same order as in the batch. So, the only reliable way to get IDs for 
inserted records – split the batch.{_}" 
source: https://jpa-buddy.com/blog/the-ultimate-guide-on-db-generated/

Since the loan transactions are ordered primarily based on transaction id and 
secondarily based on the primary key if multiple transactions with the same 
transaction date got reverse-replayed the order of the transactions might be 
changed and hence not consistent.

This could be a major problem, however it can be considered as an edge case in 
most situations.
h3. Solution

*Step 1* - Ordering should be based on {{transaction date}} + {{creation date}} 
+ {{ID}} in this order (For years mysql was used with second precision. That 
implies keeping the ID in the ordering sequence.)

*Step 2* - Set precision of 6 for DATETIME / TIMESTAMP for Mysql / MariaDB 
(PostgresDB is not effected, by default it is using precision of 6 digits after 
seconds)

*It should not cause any backward compatibility issues by default, but having 
more precision we can rely on the ordering by creation date time for the same 
day transactions!*

*Moreover, the* {{LoanTransactionComparator}} *was using* {{creation date 
time}} *as the secondary ordering attribute since 2015!*

*Acceptance criteria*
 * The order of the transactions shall be consistent after the reverse-replaying
 * The order of the reverse-replayed transactions shall match with the original 
order


> Random order of primary key generation at reverse-replaying multiple 
> transactions
> ---------------------------------------------------------------------------------
>
>                 Key: FINERACT-1946
>                 URL: https://issues.apache.org/jira/browse/FINERACT-1946
>             Project: Apache Fineract
>          Issue Type: Bug
>    Affects Versions: 1.8.3
>            Reporter: Adam Saghy
>            Priority: Major
>
> Due to the nature of JPA specification the order of the persistence of the 
> managed entities are not defined.
> When multiple entities are reverse-replayed the new entities will be 
> persisted not in a defined order hence the IDENTITY primary key generation:
> "{_}Since the provider needs to get the generated ID after each 
> {{{}INSERT{}}}, it splits the batch operation to single {{INSERT}} operators 
> and fetches the generated ID value after each execution. We just cannot send 
> a batch of {{{}INSERT statements and get a batch of generated IDs because we 
> won’t be able to associate generated IDs to JPA objects reliably. The reason 
> is that database does not guarantee that the order of the generated IDs will 
> be the same as the order of INSERTS{}}}. Moreover, {{INSERT}} statements may 
> not be executed in the same order as in the batch. So, the only reliable way 
> to get IDs for inserted records – split the batch.{_}" 
> source: [https://jpa-buddy.com/blog/the-ultimate-guide-on-db-generated/]
> Since the loan transactions are ordered primarily based on transaction id and 
> secondarily based on the primary key if multiple transactions with the same 
> transaction date got reverse-replayed the order of the transactions might be 
> changed and hence not consistent.
> This could be a major problem, however it can be considered as an edge case 
> in most situations.
> h3. Solution
> *Step 1* - Ordering should be based on {{transaction date}} + {{creation 
> date}} + {{ID}} in this order (For years mysql was used with second 
> precision. That implies keeping the ID in the ordering sequence.)
> *Step 2* - Set precision of 6 for DATETIME / TIMESTAMP for Mysql / MariaDB 
> (PostgresDB is not effected, by default it is using precision of 6 digits 
> after seconds)
> *It should not cause any backward compatibility issues by default, but having 
> more precision we can rely on the ordering by creation date time for the same 
> day transactions!*
> *Moreover, the* {{LoanTransactionComparator}} *was using* {{creation date 
> time}} *as the secondary ordering attribute since 2015!*
> *Acceptance criteria*
>  * The order of the transactions shall be consistent after the 
> reverse-replaying
>  * The order of the reverse-replayed transactions shall match with the 
> original order



--
This message was sent by Atlassian Jira
(v8.20.10#820010)

Reply via email to