Skip to content

FINERACT-274: Not able to create the same datatable which was rejected by the maker checker before#5495

Open
edk12564 wants to merge 1 commit intoapache:developfrom
edk12564:FINERACT-274
Open

FINERACT-274: Not able to create the same datatable which was rejected by the maker checker before#5495
edk12564 wants to merge 1 commit intoapache:developfrom
edk12564:FINERACT-274

Conversation

@edk12564
Copy link
Contributor

@edk12564 edk12564 commented Feb 15, 2026

JIRA: FINERACT-274, FINERACT-672, FINERACT-673, FINERACT-674, FINERACT-675, FINERACT-676

Problem

According to FINERACT-274, when a new datatable was rejected in the maker checker process, it creates an orphaned table by mistake, forcing developers to delete the table manually in their database. I've gone ahead and fixed this issue by adding a datatable cleanup service for maker checker rejections. More on this below.

To reproduce the problem:

  1. Startup a MariaDB instance of Fineract
  2. Make sure global maker-checker is on.
  3. Make sure maker-checker is on for datatable creation
  4. Login as a maker (not a super-user) user to frontend dev server
  5. Create a new datatable
  6. Login as a checker user.
  7. Deny the datatable creation.
  8. Examine the database and find orphaned table.
Screenshot 2026-02-13 at 7 41 23 PM

Screenshot 2026-02-13 at 7 41 13 PM
  1. Reconfirm by trying to create datatable with same name, which displays an error message: data table already exists.
Screenshot 2026-02-13 at 6 26 30 PM

Changes

The problem was found to affect the group, center, loan account, office, and savings accounts levels.

After diagnosing the issue, I found that during data table creation events, the transaction in maker-checker gets rolled backed. However, it turns out that MariaDB does not add DDL (data table changes) queries to a transaction, meaning when the maker-checker system rolls everything back for checking, the DDL actually executes and makes the table anyways. This means that when the data table is rejected, the orphaned data table exists in the database. PostgreSQL includes DDL as part of the transaction boundary, meaning it is not an issue when PostgreSQL is used.

To fix the issue, I added a cleanup service after every maker-checker rejection that checks if the rejection was a data table rejection. If that was the case, it cleans up the data table in question. If not, it continues as normal. This structure allows us to keep as much original logic as possible, while working in both PostgreSQL and MariaDB use cases.

To test my changes, I also added an integration test that tests the process of data table creation, maker-checker events, and another data table creation to determine if the data table was properly removed. I do this over the group, center, loan account, office, and saving account levels to make sure they don't produce the bugs mentioned in the various tickets.

I tried to follow convention as much as possible, but I may have missed some things so feedback is very welcome!

Results

Tests all pass:

For MariaDB:
Screenshot 2026-02-14 at 8 23 45 PM

For PostgreSQL:
Screenshot 2026-02-14 at 8 25 20 PM

Reproducing the issue no longer results in a "data table already exists" error:

Demo video is too big for Github, but here is the list of tables after submitting the maker command. You can see the test table.
Screenshot 2026-02-14 at 11 15 41 PM

And here is the list of tables after rejecting with the checker user. You can see there is no test table.
Screenshot 2026-02-14 at 11 16 24 PM

Checklist

Please make sure these boxes are checked before submitting your pull request - thanks!

  • Write the commit message as per our guidelines
  • Acknowledge that we will not review PRs that are not passing the build ("green") - it is your responsibility to get a proposed PR to pass the build, not primarily the project's maintainers.
  • Create/update unit or integration tests for verifying the changes made.
  • Follow our coding conventions.
  • Add required Swagger annotation and update API documentation at fineract-provider/src/main/resources/static/legacy-docs/apiLive.htm with details of any API changes
  • This PR must not be a "code dump". Large changes can be made in a branch, with assistance. Ask for help on the developer mailing list.

Your assigned reviewer(s) will follow our guidelines for code reviews.

@edk12564 edk12564 force-pushed the FINERACT-274 branch 2 times, most recently from e473b39 to 54ae254 Compare February 15, 2026 05:41
Copy link
Contributor

@IOhacker IOhacker left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

Copy link
Contributor

@adamsaghy adamsaghy left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I dont think any of the changes are needed.

The attached integration tests are green without messing with transaction boundaries, neither having the "cleanup".

The maker-checker is fully rolled back, so no left over data. You can create datatable if it was rejected priorly.

Kindly asking you to double check!

@edk12564
Copy link
Contributor Author

edk12564 commented Feb 18, 2026

I dont think any of the changes are needed.

The attached integration tests are green without messing with transaction boundaries, neither having the "cleanup".

The maker-checker is fully rolled back, so no left over data. You can create datatable if it was rejected priorly.

Kindly asking you to double check!

Firstly, thank you adam for the review!

I did as you said and double checked by running a few tests, both in MariaDB and Postgres. Can I ask what database you used to check the changes? I think the database matters because the issue should only affect MariaDB.

To clarify, the behavior of the solution and tests with a Postgres database should be a "no-op". This is because of how MariaDB handles DDL statements like creating new tables. So the problem doesn't even occur when Postgres databases are used.

I tried to replicate in a few circumstances and got the results below. You can also see the cleanup commented out in (without cleanup) and not commented out in (with cleanup).

MariaDB (without cleanup):
Screenshot 2026-02-17 at 10 06 49 PM

MariaDB (with cleanup):
Screenshot 2026-02-17 at 10 19 26 PM

Postgres (without cleanup):
Screenshot 2026-02-17 at 10 07 51 PM

As for the extra @transactional I added. This was just to ensure that the removal didn't happen without the rest of the items in rejectEntry(). But thinking about it now, I don't think this is necessary, since MariaDB will commit this DDL even if it is in @transactional, just like for the table creation. I will make another change without this in there!

Please let me know if there's something I missed. I understand I am new and thus prone to making mistakes.

@adamsaghy
Copy link
Contributor

I dont think any of the changes are needed.
The attached integration tests are green without messing with transaction boundaries, neither having the "cleanup".
The maker-checker is fully rolled back, so no left over data. You can create datatable if it was rejected priorly.
Kindly asking you to double check!

Firstly, thank you adam for the review!

I did as you said and double checked by running a few tests, both in MariaDB and Postgres. Can I ask what database you used to check the changes? I think the database matters because the issue should only affect MariaDB.

To clarify, the behavior of the solution and tests with a Postgres database should be a "no-op". This is because of how MariaDB handles DDL statements like creating new tables. So the problem doesn't even occur when Postgres databases are used.

I tried to replicate in a few circumstances and got the results below. You can also see the cleanup commented out in (without cleanup) and not commented out in (with cleanup).

MariaDB (without cleanup): Screenshot 2026-02-17 at 10 06 49 PM

MariaDB (with cleanup): Screenshot 2026-02-17 at 10 19 26 PM

Postgres (without cleanup): Screenshot 2026-02-17 at 10 07 51 PM

As for the extra @transactional I added. This was just to ensure that the removal didn't happen without the rest of the items in rejectEntry(). But thinking about it now, I don't think this is necessary, since MariaDB will commit this DDL even if it is in @transactional, just like for the table creation. I will make another change without this in there!

Please let me know if there's something I missed. I understand I am new and thus prone to making mistakes.

OMG mariadb and mysql... OMG.... :(

@edk12564
Copy link
Contributor Author

I dont think any of the changes are needed.
The attached integration tests are green without messing with transaction boundaries, neither having the "cleanup".
The maker-checker is fully rolled back, so no left over data. You can create datatable if it was rejected priorly.
Kindly asking you to double check!

Firstly, thank you adam for the review!
I did as you said and double checked by running a few tests, both in MariaDB and Postgres. Can I ask what database you used to check the changes? I think the database matters because the issue should only affect MariaDB.
To clarify, the behavior of the solution and tests with a Postgres database should be a "no-op". This is because of how MariaDB handles DDL statements like creating new tables. So the problem doesn't even occur when Postgres databases are used.
I tried to replicate in a few circumstances and got the results below. You can also see the cleanup commented out in (without cleanup) and not commented out in (with cleanup).
MariaDB (without cleanup): Screenshot 2026-02-17 at 10 06 49 PM
MariaDB (with cleanup): Screenshot 2026-02-17 at 10 19 26 PM
Postgres (without cleanup): Screenshot 2026-02-17 at 10 07 51 PM
As for the extra @transactional I added. This was just to ensure that the removal didn't happen without the rest of the items in rejectEntry(). But thinking about it now, I don't think this is necessary, since MariaDB will commit this DDL even if it is in @transactional, just like for the table creation. I will make another change without this in there!
Please let me know if there's something I missed. I understand I am new and thus prone to making mistakes.

OMG mariadb and mysql... OMG.... :(

😄 😄 I heard from the recent meeting, but is MariaDB and MySQL getting phased out slowly? I understand we want to be accomodative to different solutions, but I'm getting the sense this doesn't apply here?

@adamsaghy
Copy link
Contributor

I dont think any of the changes are needed.
The attached integration tests are green without messing with transaction boundaries, neither having the "cleanup".
The maker-checker is fully rolled back, so no left over data. You can create datatable if it was rejected priorly.
Kindly asking you to double check!

Firstly, thank you adam for the review!
I did as you said and double checked by running a few tests, both in MariaDB and Postgres. Can I ask what database you used to check the changes? I think the database matters because the issue should only affect MariaDB.
To clarify, the behavior of the solution and tests with a Postgres database should be a "no-op". This is because of how MariaDB handles DDL statements like creating new tables. So the problem doesn't even occur when Postgres databases are used.
I tried to replicate in a few circumstances and got the results below. You can also see the cleanup commented out in (without cleanup) and not commented out in (with cleanup).
MariaDB (without cleanup): Screenshot 2026-02-17 at 10 06 49 PM
MariaDB (with cleanup): Screenshot 2026-02-17 at 10 19 26 PM
Postgres (without cleanup): Screenshot 2026-02-17 at 10 07 51 PM
As for the extra @transactional I added. This was just to ensure that the removal didn't happen without the rest of the items in rejectEntry(). But thinking about it now, I don't think this is necessary, since MariaDB will commit this DDL even if it is in @transactional, just like for the table creation. I will make another change without this in there!
Please let me know if there's something I missed. I understand I am new and thus prone to making mistakes.

OMG mariadb and mysql... OMG.... :(

😄 😄 I heard from the recent meeting, but is MariaDB and MySQL getting phased out slowly? I understand we want to be accomodative to different solutions, but I'm getting the sense this doesn't apply here?

Well... not as quickly as I want.. so probably this year we will still supporting 3 db engines :(

private final CommandProcessingService processAndLogCommandService;
private final SchedulerJobRunnerReadService schedulerJobRunnerReadService;
private final ConfigurationDomainService configurationService;
private final DatatableRejectionCleanupService ifDatatableRejectionThenCleanup;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Lets rename it something more generic, like: CleanUpService and have it as an interface only. Lets inject it as a List, so multiple implementations are allowed to be used (even if there is just one for now). If the list is null, we can skip it. if not a foreach we can call all of them. The implementation classes responsibilities to decide whether there is something to be done or not.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'll get to work on this now!

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just pushed my changes. Please let me know if it is good!

Copy link
Contributor

@adamsaghy adamsaghy left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Kindly see my recommendations!

@edk12564 edk12564 force-pushed the FINERACT-274 branch 2 times, most recently from 06610d7 to 58ecf98 Compare February 19, 2026 17:49
- added datatable cleanup service after a maker checker rejection
- checks if datatable was created in rejected command source, and if so deletes it
- added integration test to assess orphan table deletion
- accounted for MariaDB and PostgreSQL
- accounted for group, center, loan account, office, and savings account levels
- utilized more generic interface with options for more extensibility
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants

Comments