Skip to content

data-store-java: inside a UnitOfWork the document's synchronous total recompute ends at 0.00 - a create-from with items: produces an invoice whose lines are right and whose Total is 0 (14.48.0 regression from #7081) #7096

Description

@delchev

What happens

Since #7081 a generates: create-from runs header + lines + sourceStatus flip inside one UnitOfWork. The generated document now comes out with every total 0.00 although its lines exist and are correct, and nothing ever recomputes it.

Reproduced on dirigiblelabs/dirigible:14.48.0 with base-timesheets invoice-from-timesheet (items EmployeeTimesheet -> SalesInvoiceItem, quantity: totalHours, price: rate) against a base-sales-invoices target regenerated on 14.48.0 (so the target's repositories are the current templates):

POST .../InvoiceFromTimesheetGenerate/run {"id": 3}          -> 200, SalesInvoice 5
GET  .../SalesInvoiceItemController  (SalesInvoice == 5)      -> [("QA Employee One", Quantity 176, Price 60, Net 10560.00)]
GET  .../SalesInvoiceController/5   at t+0s / +5s / +15s / +3min -> Net 0.0, Vat 0.0, Total 0.0, Payable 0.0, Balance 0.0

Control, same instance, outside a unit of work: POST .../SalesInvoiceItemController {"SalesInvoice": 2, "Quantity": 1, "Price": 10, ...} -> the header of invoice 2 is recomputed at once (Net 8810 = the generated 8800 line, which had also been ignored, + 10). So the recompute machinery is fine; it is the run inside the unit that loses its result.

The recompute is the synchronous one every line write performs (SalesInvoiceItemRepository.save -> new SalesInvoiceRepository().recalculate(saved.SalesInvoice)), which findByIds the header, findAlls the lines by FK and persists the sums through the targeted updateProperties (a createMutationQuery("update ... where id = :id")). Inside the unit both reads and writes join UNIT_OF_WORK.get().session (JavaEntityStore.read/write), while the inserts are session.persist(entityName, map). Two candidate mechanisms, both consistent with the observation and both fixable in the store rather than in the templates:

  1. the bulk HQL update runs against the database before the still-pending persist of the header is flushed, so it updates 0 rows, and the header is then inserted at commit with the zeros it was built with;
  2. the lines query inside the same session does not see the pending line inserts (no auto-flush for the dynamic-map entity), so the sum is 0 and 0 is what gets written.

Either way the fix belongs where the unit is bound: flush the session before a query / mutation query issued inside a unit (or make the mutation path go through the managed entity), so that "reads inside the block see the block's own writes" (#7081's own statement) also holds for the write-then-aggregate pattern every document repository uses.

Why it matters

A generated invoice with lines and Total 0.00 is the empty-document class QG-2/QG-3 exist for, produced by the platform's own generator on every create-from with items: (timesheet -> invoice, proforma -> invoice, quotation -> order, order -> invoice). On 14.46.0 (each save its own transaction) the totals were right; this is a 14.48.0 regression introduced by the fix for #7069, and it would ship to sta with the 14.48.0 train.

Expected

The header's totals after a create-from equal the sum of its lines, exactly as after a line POSTed through REST. JavaUnitOfWorkIT gets the write-then-query-then-targeted-update case; IntentEngineIT's create-from with items: asserts the header total.

Found 2026-09-07 adapting base-timesheets for the 14.48.0 train (BusinessIntents/base-timesheets#19, PR pending). Related: #7069 / #7081 (the unit of work), #7068 / #7080.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions