miniGl to do accounting for a mobile wallet

166 views
Skip to first unread message

cap10mycap10

unread,
Dec 26, 2024, 6:47:02 AM12/26/24
to jPOS Users
I have been playing around with miniGl and i have managed to run the tests.

Would miniGL work well in a scenario where i have a wallet and i want to create wallet accounts for ordinary users, merchant and agents, example scenario below :

1. users deposits funds into their wallet
2. user pays merchant for goods and services and is charged a fee( the merchant gets the principal amount  less merchant discount rate)
3. agent sells value added services such as bill payments and airtime topups and they get a commission.

in this case i will have 1...n ordinary user accounts, merchant accounts and agent accounts.

Regards

Alejandro Revilla

unread,
Dec 26, 2024, 7:15:49 AM12/26/24
to jpos-...@googlegroups.com

miniGL is a general-purpose double-entry, multi-layer accounting system. As long as your transactions align with the manual processes your accounting team uses to record business activities, you can implement them in miniGL. At its core, miniGL operates on simple principles: credits and debits to the appropriate accounts.

Regarding your items:

1. Users Deposit Funds into Their Wallet

From the system's perspective, when a user deposits funds, you are receiving money (a 'debit' into an asset account), while the wallet balance represents a liability. Thus, you credit the wallet account in the liabilities section. This is a straightforward example; in practice, you may have escrow accounts that are already categorized as liabilities, but your accounting team will define these specifics.

2. User Pays Merchant for Goods

When a user pays a merchant, the liability shifts. Instead of owing the {card, wallet}holder, you now owe the merchant or its acquirer. The corresponding general ledger transaction will:

  • Debit the wallet,
  • Credit the merchant (or acquirer),
  • Credit earned fees (recorded in the "earnings" section of the chart of accounts).

3. Agent Sells Value-Added Services

miniGL provides full flexibility to create accounts for agents and sub-agents. This enables detailed tracking and management of transactions involving value-added services. This is where miniGL’s innovation truly stands out: its layering capability. For more details, see miniGL Layers. While this concept may initially seem complex for the accounting team to grasp, it offers powerful solutions for scenarios like managing cash-in and cash-out fees.

For example, we have a wallet system based on miniGL with an ambitious fee plan, you could implement a structure where money incurs a fee when it enters the system but becomes free to use when it leaves. However, inter-wallet transfers reset this status, ensuring that money transferred internally between customers pays a fee at the cash-out stage. Layers (as well as 'tags') make implementing such policies seamless and efficient.

Scaling with miniGL
You may also have heard of jCard, an interface bridging the ISO-8583 world with a double-entry record system based on miniGL. At least two jCard customers are currently processing over one billion cards on file (many more at lower scale). Each card has at least one miniGL account, demonstrating the system's scalability. These implementations often run in properly sharded environments or within per-program containers, managing hundreds of millions of cards each.

Looking ahead, we’re developing a new version of miniGL—massiveGL—designed to scale even further, just in case every human on the planet wants to have an account :)


--
--
jPOS is licensed under AGPL - free for community usage for your open-source project. Licenses are also available for commercial usage. Please support jPOS, contact: sa...@jpos.org
---
You received this message because you are subscribed to the Google Groups "jPOS Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to jpos-users+...@googlegroups.com.
To view this discussion visit https://groups.google.com/d/msgid/jpos-users/268b101c-b56c-46d3-bab4-21a7ce3c74ean%40googlegroups.com.

Mapfunde Venon

unread,
Dec 28, 2024, 8:24:31 PM12/28/24
to jpos-...@googlegroups.com, Alejandro Revilla
Hello

Thanks @Alejandro Revilla , I have managed to tweak the tests with a minimal Chart of Accounts represented below:

1. Assets

  • 1000 Cash and Cash Equivalents

    • 1010 Cash on Hand

    • 1020 Cash in Bank

6. Liabilities

  • 2000 Customer Deposits

    • 2010 Checking Accounts--created 2 checking accounts under this.

and i modified the testdata.xml to be as below:

<?xml version="1.0" ?>
<!DOCTYPE minigl SYSTEM 'http://jpos.org/dtd/minigl.dtd'>
<minigl>
<create-schema />

<user>
<nick>cap10mycaap10</nick>
<name>Venon Mapfunde</name>
<grant>read</grant>
<grant>write</grant>
<grant>grant</grant>
</user>
<user>
<nick>travis</nick>
<name>Travis build</name>
<grant>read</grant>
<grant>write</grant>
<grant>grant</grant>
</user>

<!-- ADD YOUR username here -->

<user>
<nick>bob</nick>
<name>Bob Book Keeper</name>
<grant>read</grant>
<grant>write</grant>
<grant>grant</grant>
</user>

<user>
<nick>eve</nick>
<name>Eve Noperm</name>
</user>

<currency id="840">
<symbol>USD</symbol>
<name>US Dollars</name>
</currency>



<chart-of-accounts code="TestChart" created="20050101">
<description>Test Chart</description>
<composite-account code="1" type="debit" >
<description>Assets</description>
<composite-account code="10" type="debit" >
<description>Cash</description>
<account code="1010" type="debit" currency="840">
<description>Cash on Hand</description>
</account>

<account code="1020" type="debit" currency="840">
<description>Cash in Bank</description>
</account>

</composite-account>

</composite-account>
<composite-account code="6" type="credit" >
<description>Liabilities</description>
<composite-account code="60" type="credit">
<description>Customer Deposits</description>
<composite-account code="6064" type="credit" >
<description>Checking Accounts</description>
<account code="6064230000000201" type="credit" currency="840">
<description>Checking Account - 6064230000000201</description>
</account>
<account code="6064230000000409" type="credit" currency="840">
<description>Checking Account - 6064230000000409</description>
</account>
</composite-account>
</composite-account>
</composite-account>

</chart-of-accounts>

<!--
Layers plan:

Reporting currency (840) goes to layer 0 (reporting currency)
Uruguayan pesos (858) goes to layer 858
Virtual layer 1 is a trip fund
Virtual layer 2 is a budget layer

-->

<journal>
<name>TestJournal</name>
<start>20010101</start>
<!-- <end>20301231</end> -->
<status>open</status>
<chart>TestChart</chart>
<grant user="bob">post</grant>
<grant user="bob">checkpoint</grant>
<grant user="bob">summarize</grant>
<grant user="travis">post</grant>
<grant user="travis">checkpoint</grant>
<grant user="travis">summarize</grant>
<rule clazz="org.jpos.gl.rule.CanPost">
Verify permissions, start/end dates, status, and chart
</rule>
<rule clazz="org.jpos.gl.rule.DoubleEntry">
Verify that credits equals debits
<layers>0</layers>
</rule>

<rule clazz="org.jpos.gl.rule.FinalMinBalance" account="6064230000000201">
Check that the account has always a balance greater than 0.00
<param>0.00</param>
<layers>0,1</layers>
</rule>

<rule clazz="org.jpos.gl.rule.FinalMinBalance" account="6064230000000409">
Check that the account has always a balance greater than 0.00
<param>0.00</param>
<layers>0,1</layers>
</rule>

<rule clazz="org.jpos.gl.rule.FinalMaxBalance" account="6064230000000201">
Put a limit to Bob's wallet balance
<param>50000.00</param>
<layers>0,1</layers>
</rule>
<rule clazz="org.jpos.gl.rule.FinalMaxBalance" account="6064230000000409">
Put a limit to Alice's wallet balance
<param>10000.00</param>
<layers>0,1</layers>
</rule>
</journal>


<transaction post-date="20050101" date="20050101130000" journal="TestJournal">
<detail>Bob's initial deposit</detail>
<tags>tag1 tag2</tags>

<entry account="1010" type="debit">
<detail>Bob Check #001 (USD layer 0)</detail>
<tags>the-debit</tags>
<amount>1000.00</amount>
</entry>
<entry account="6064230000000201" type="credit">
<detail>Bob Initial cash (USD layer 0)</detail>
<tags>the-credit</tags>
<amount>1000.00</amount>
</entry>

</transaction>

<transaction post-date="20050101" date="20050101130000" journal="TestJournal">
<detail>Alice's initial deposit</detail>
<tags>tag1 tag2</tags>

<entry account="1010" type="debit">
<detail>Alice Check #001 (USD layer 0)</detail>
<tags>the-debit</tags>
<amount>1000.00</amount>
</entry>
<entry account="6064230000000409" type="credit">
<detail>Alice Initial cash (USD layer 0)</detail>
<tags>the-credit</tags>
<amount>1000.00</amount>
</entry>

</transaction>


</minigl>

I also added some tests:  

@Test
public void testCreateTransactions() throws Exception {
Journal j = gls.getJournal("TestJournal");
Transaction tx = gls.beginTransaction();
start("createTransaction");
GLTransaction txn = createTransaction();
gls.post(j, txn);
checkPoint("post ");
tx.commit();
checkPoint("commit");
gls.session().clear();

}

@Test
private GLTransaction createTransaction() throws Exception {
GLTransaction txn = new GLTransaction("Transfer of 400");
txn.setPostDate(Util.parseDateTime("20241228120000"));

var debitAccount = getAccount("6064230000000201");
var creditAccount = getAccount("6064230000000409");

BigDecimal amount = new BigDecimal(400).setScale(2);


txn.createDebit(debitAccount, amount, "Test Transfer " + amount);


txn.createCredit(creditAccount, amount, "Test Transfer " + amount);

return txn;
}

@Test
private FinalAccount getAccount(String accountNumber) throws Exception {

FinalAccount acct = gls.getFinalAccount("TestChart", accountNumber);
return acct;
}

@Test
public void findBalance() throws Exception {
testCreateTransactions();
Journal j = gls.getJournal("TestJournal");
var x = gls.getBalance(j, getAccount("6064230000000201"), new short[]{0});
assert (x.compareTo(new BigDecimal(600)) == 0);
}


My next task is to do this in a real code not test and I am still to figure out how to set up the database connection. My goal is to be able to create some rest controllers that recieve instructions to create an account and do some financial transactions.

Venon Mapfunde(PMP,Msc Software Engineering,Bsc Computer Science & Mathematics) Tel:+263 775 091 262 Email:taka...@gmail.com Skype: venon.mapfunde


Alejandro Revilla

unread,
Dec 30, 2024, 10:50:13 AM12/30/24
to jpos-...@googlegroups.com
Excellent. 

FYI, this is the jCard API that includes MiniGL stuff: https://transactilityinc.github.io/jcard/#tag/MiniGL

While jCard is not open source, you can use its API as an example.



cap10mycap10

unread,
Jan 4, 2025, 2:29:28 PMJan 4
to jPOS Users
Thanks for the jCard Api, it helped see me see what is possible.  I have a few questions: 
1. Is there a way i can set a Rule on an account programmatically when i create it, eg I want to create account x which follows double entry?
2. Lets say I have done 10000 transactions(i.e 10000 entries on a specific account ) and i want to calculate the balance but I want it to be quick, i see there is balance cache and checkpoint, how do i use these?
3. Tags and Layers, I last did accounting in high school so many moons ago and from what i could understand from the blog: https://jpos.org/blog/2006/09/minigl-layers/ it looks like layer 0 is the final stage and 1 could a pending stage:  eg:  lets assume i have a Agent doing a bill payment but I have to hold funds before making an external call to 3rd party service, I will post these funds to layer 1 and when the 3rd party call is successful, i can then post the amount to layer 0.  And tags, not still sure what purpose they serve.
4. How do i make sure i dont post the same transaction--I did not see something like a reference i can post with my transaction to ensure that no transaction is repeaated.

Alejandro Revilla

unread,
Jan 7, 2025, 5:06:37 PMJan 7
to jpos-...@googlegroups.com

Its great to hear that the jCard API has been helpful for you. Ill address your questions below:

  1. Is there a way I can set a Rule on an account programmatically when I create it, e.g., for double-entry?

    Rules in jPOS are applied at the Journal/Layer level. For example, you can apply rules like DoubleEntry to specific layers. In jCard, this is configured in a minigl-setup.xml file, which might look like this:

    <journal>
     <name>jcard</name>
     <start>20010101</start>
     <!--<end>20201231</end>-->
     <status>open</status>
     <chart>jcard</chart>
     <layer id="858">Pesos</layer>
     <layer id="1858">Pending Pesos</layer>
     <layer id="840">Dollars</layer>
     <layer id="1840">Pending Dollars</layer>
     <layer id="2840">Credit line, USD</layer>

     <grant user="admin">read</grant>
     <grant user="admin">post</grant>
     <grant user="admin">checkpoint</grant>
     <grant user="admin">summarize</grant>

     <rule clazz="org.jpos.gl.rule.CanPost">
      Verifies permissions, start/end dates, status, and chart
     </rule>
     <rule clazz="org.jpos.gl.rule.DoubleEntry">
      Verifies that credits equals debits
      <layers>858,840,1858,1840</layers>
     </rule>

    These rules are imported during the initial system setup using the glimport CLI command. While you can programmatically create or adjust these rules by referencing the glimport source code, they are typically designed to remain static once applied. For instance, enabling double-entry on specific journals or layers is usually a long-term configuration.

  2. How can I calculate the balance quickly after 10,000 transactions? How do Balance Cache and Checkpoints work?

    Both Balance Cache and Checkpoints improve balance computation efficiency but serve different purposes:

    • Balance Cache tracks the most recent balance, regardless of the transactions postDate. This is especially useful in issuer systems where you need a fast computation of the available balance to decide whether a transaction should be approved or declined.

    • Checkpoints, on the other hand, account for the postDate and are more resource-intensive to compute. They’re ideal for generating statements for specific periods. For example, you can create a checkpoint at the end of a month so that subsequent statements don’t need to process the entire transaction history again.

  3. Tags and Layers: What are their roles? Dont worry about your confusion, Im sure you havent learn this in high school because its some kind of jPOS invention. We have a hard time explaining the concept even to professional CPAs, but once they get it, they love it.

    • Tags: These are essentially metadata for transactions, stored to support application-specific use cases. For example, if you tag certain entries with #fee, you can later identify and include or exclude those entries (e.g., fees that shouldnt be reversed during a transaction reversal).

    • Layers: These act as sub-journals within a journal. The layer number is defined as part of your applications logic, and its use depends on your layer plan. For instance, in jCard, we use ISO-4217 currency codes (e.g., 840 for USD) and add offsets for specific purposes:

      • +1000: Pending transactions (e.g., 1840 for pending USD).

      • +2000: Credit allowances.

      • +3000: On-hold credits (e.g., for refunds or potentially fraudulent transactions).

      For example, if you receive a refund that shouldn’t be immediately available, you could post it to the 3840 layer. A batch process or authorized operator could later ground the funds by reversing the entry in 3840 and posting it to 840 in a single GLTransaction.

  4. How do I make sure i dont post the same transactionI did not see something like a reference I can post with my transaction to ensure that no transaction is repeated..

    Thats where the surrounding application comes into play. In jCard we have a Tranlog record with all the transaction metadata, and using that metadata, that includes the RRN, PAN, Amount, currency, MTI, etc. etc. we decide if the transaction needs to be posted to miniGL or has to be handled as a retransmission with no financial impact.


Umoh Bassey-Duke

unread,
May 16, 2025, 10:52:50 AMMay 16
to jPOS Users
Hi Alejandro,

A quick follow up on Layers. In the example you gave, how would one post to the 3840 layer? Seeing that the double entry rule would fail. I cannot debit the cash account on layer 840 and credit the customer on layer 3840 for example.
For more context

A customer wants to withdraw funds.
1. Debit layer 840  and credit layer 1840 (Customer's available balance reduces by the amount)
2. Call third party to perform transaction. 
3. On successful response: Debit layer 1840 and credit the Settlement  Holding Account on layer 840.

Another question, we have a requirement to enforce certain transaction limits e.g. Daily debits , cumulative debits, etc. What would be the best practice for doing this in an efficient manner? The two approaches we're following is to have a rule that calculates it dynamically at execution time, second approach would be to create an account that gets filled up every day and each transaction depletes the balance.

Looking forward to hearing your recommendations.

Alejandro Revilla

unread,
May 16, 2025, 10:58:42 AMMay 16
to jpos-...@googlegroups.com

The DoubleEntry rule can be configured to apply only to certain layers—such as the accounting layer (offset=0) and the pending layer (offset=1000)—while being relaxed in others, like the layer with offset=3000. This allows you to have a GL transaction with a matching credit/debit in the 840 layer and a single-leg entry, for example, in the 3840 layer.

That’s one option. For greater control, you can define a bridge account in the chart of accounts and use it as the counterparty for entries you want to register in the 3840 layer.

It might seem confusing at first, but this is standard accounting practice—your accounting team will fully understand.

Any CPA in the group that could explain this using better accounting terminology?



--
--
jPOS is licensed under AGPL - free for community usage for your open-source project. Licenses are also available for commercial usage. Please support jPOS, contact: sa...@jpos.org
---
You received this message because you are subscribed to the Google Groups "jPOS Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to jpos-users+...@googlegroups.com.

cap10mycap10

unread,
May 26, 2025, 10:33:27 AMMay 26
to jPOS Users
Hello Alejandro

I have facing an issue where if an exception occurs, the next  call to minigl  fails.  Example if i try to create an account that already exists, the response takes too long to come back and then if i try to create one that does not exist, it fails.  Below is the code to create the account:


public void createAccount(String chartName, String accountNumber, String description, String parentCode, String currencyCode) throws Exception {
Transaction tx = gls.beginTransaction(5);
try {
start("createAccount");

CompositeAccount cards = gls.getCompositeAccount(chartName, parentCode);
Account acct = new FinalAccount();
acct.setCode(parentCode.concat(accountNumber));
acct.setType(Account.CREDIT);
acct.setDescription(description);
acct.setCurrencyCode(currencyCode);
acct.setCreated(new Date());
gls.addAccount(cards, acct, true);
gls.session().evict(acct);
end("createAccount");
tx.commit();
gls.session().evict(cards);
applyRules(acct);
} catch (Exception e) {
tx.rollback();
gls.close();
e.printStackTrace();
log.error(e.getMessage());
throw new RuntimeException("Account creation failed");
}
}


Exception: on this line: gls.addAccount(cards, acct, true);

org.hibernate.PessimisticLockException: could not execute statement
at org.hibernate.dialect.MySQLDialect$3.convert(MySQLDialect.java:547)
at org.hibernate.exception.internal.StandardSQLExceptionConverter.convert(StandardSQLExceptionConverter.java:37)
at org.hibernate.engine.jdbc.spi.SqlExceptionHelper.convert(SqlExceptionHelper.java:113)
at org.hibernate.engine.jdbc.spi.SqlExceptionHelper.convert(SqlExceptionHelper.java:99)
at org.hibernate.engine.jdbc.internal.ResultSetReturnImpl.executeUpdate(ResultSetReturnImpl.java:200)
at org.hibernate.dialect.identity.GetGeneratedKeysDelegate.executeAndExtract(GetGeneratedKeysDelegate.java:58)
at org.hibernate.id.insert.AbstractReturningDelegate.performInsert(AbstractReturningDelegate.java:43)
at org.hibernate.persister.entity.AbstractEntityPersister.insert(AbstractEntityPersister.java:3279)
at org.hibernate.persister.entity.AbstractEntityPersister.insert(AbstractEntityPersister.java:3885)
at org.hibernate.action.internal.EntityIdentityInsertAction.execute(EntityIdentityInsertAction.java:84)
at org.hibernate.engine.spi.ActionQueue.execute(ActionQueue.java:645)
at org.hibernate.engine.spi.ActionQueue.addResolvedEntityInsertAction(ActionQueue.java:282)
at org.hibernate.engine.spi.ActionQueue.addInsertAction(ActionQueue.java:263)
at org.hibernate.engine.spi.ActionQueue.addAction(ActionQueue.java:317)
at org.hibernate.event.internal.AbstractSaveEventListener.addInsertAction(AbstractSaveEventListener.java:330)
at org.hibernate.event.internal.AbstractSaveEventListener.performSaveOrReplicate(AbstractSaveEventListener.java:287)
at org.hibernate.event.internal.AbstractSaveEventListener.performSave(AbstractSaveEventListener.java:193)
at org.hibernate.event.internal.AbstractSaveEventListener.saveWithGeneratedId(AbstractSaveEventListener.java:123)
at org.hibernate.event.internal.DefaultSaveOrUpdateEventListener.saveWithGeneratedOrRequestedId(DefaultSaveOrUpdateEventListener.java:194)
at org.hibernate.event.internal.DefaultSaveEventListener.saveWithGeneratedOrRequestedId(DefaultSaveEventListener.java:38)
at org.hibernate.event.internal.DefaultSaveOrUpdateEventListener.entityIsTransient(DefaultSaveOrUpdateEventListener.java:179)
at org.hibernate.event.internal.DefaultSaveEventListener.performSaveOrUpdate(DefaultSaveEventListener.java:32)
at org.hibernate.event.internal.DefaultSaveOrUpdateEventListener.onSaveOrUpdate(DefaultSaveOrUpdateEventListener.java:75)
at org.hibernate.event.service.internal.EventListenerGroupImpl.fireEventOnEachListener(EventListenerGroupImpl.java:107)
at org.hibernate.internal.SessionImpl.fireSave(SessionImpl.java:672)
at org.hibernate.internal.SessionImpl.save(SessionImpl.java:665)
at org.hibernate.internal.SessionImpl.save(SessionImpl.java:660)
at org.jpos.gl.GLSession.addAccount(GLSession.java:365)
at zw.co.jugaad.service.AccountService.createAccount(AccountService.java:32)
at zw.co.jugaad.controller.AccountController.createAccount(AccountController.java:25)
at io.javalin.router.Endpoint.handle(Endpoint.kt:52)
at io.javalin.router.ParsedEndpoint.handle(ParsedEndpoint.kt:15)
at io.javalin.http.servlet.DefaultTasks.HTTP$lambda$9$lambda$7$lambda$6(DefaultTasks.kt:52)
at io.javalin.http.servlet.JavalinServlet.handleTask(JavalinServlet.kt:99)
at io.javalin.http.servlet.JavalinServlet.handleSync(JavalinServlet.kt:64)
at io.javalin.http.servlet.JavalinServlet.handle(JavalinServlet.kt:50)
at io.javalin.http.servlet.JavalinServlet.service(JavalinServlet.kt:30)
at jakarta.servlet.http.HttpServlet.service(HttpServlet.java:587)
at io.javalin.jetty.JavalinJettyServlet.service(JavalinJettyServlet.kt:52)
at jakarta.servlet.http.HttpServlet.service(HttpServlet.java:587)
at org.eclipse.jetty.servlet.ServletHolder.handle(ServletHolder.java:764)
at org.eclipse.jetty.servlet.ServletHandler.doHandle(ServletHandler.java:529)
at org.eclipse.jetty.server.handler.ScopedHandler.nextHandle(ScopedHandler.java:221)
at org.eclipse.jetty.server.session.SessionHandler.doHandle(SessionHandler.java:1580)
at org.eclipse.jetty.server.handler.ScopedHandler.nextHandle(ScopedHandler.java:221)
at org.eclipse.jetty.server.handler.ContextHandler.doHandle(ContextHandler.java:1381)
at org.eclipse.jetty.server.handler.ScopedHandler.nextScope(ScopedHandler.java:176)
at org.eclipse.jetty.servlet.ServletHandler.doScope(ServletHandler.java:484)
at org.eclipse.jetty.server.session.SessionHandler.doScope(SessionHandler.java:1553)
at org.eclipse.jetty.server.handler.ScopedHandler.nextScope(ScopedHandler.java:174)
at org.eclipse.jetty.server.handler.ContextHandler.doScope(ContextHandler.java:1303)
at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:129)
at org.eclipse.jetty.server.handler.StatisticsHandler.handle(StatisticsHandler.java:173)
at org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:122)
at org.eclipse.jetty.server.Server.handle(Server.java:563)
at org.eclipse.jetty.server.HttpChannel$RequestDispatchable.dispatch(HttpChannel.java:1598)
at org.eclipse.jetty.server.HttpChannel.dispatch(HttpChannel.java:753)
at org.eclipse.jetty.server.HttpChannel.handle(HttpChannel.java:501)
at org.eclipse.jetty.server.HttpConnection.onFillable(HttpConnection.java:287)
at org.eclipse.jetty.io.AbstractConnection$ReadCallback.succeeded(AbstractConnection.java:314)
at org.eclipse.jetty.io.FillInterest.fillable(FillInterest.java:100)
at org.eclipse.jetty.io.SelectableChannelEndPoint$1.run(SelectableChannelEndPoint.java:53)
at org.eclipse.jetty.util.thread.QueuedThreadPool.runJob(QueuedThreadPool.java:969)
at org.eclipse.jetty.util.thread.QueuedThreadPool$Runner.doRunJob(QueuedThreadPool.java:1194)
at org.eclipse.jetty.util.thread.QueuedThreadPool$Runner.run(QueuedThreadPool.java:1149)
at java.base/java.lang.Thread.run(Thread.java:833)
Caused by: com.mysql.cj.jdbc.exceptions.MySQLTransactionRollbackException: Lock wait timeout exceeded; try restarting transaction
at com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:123)
at com.mysql.cj.jdbc.exceptions.SQLExceptionsMapping.translateException(SQLExceptionsMapping.java:122)
at com.mysql.cj.jdbc.ClientPreparedStatement.executeInternal(ClientPreparedStatement.java:953)
at com.mysql.cj.jdbc.ClientPreparedStatement.executeUpdateInternal(ClientPreparedStatement.java:1098)
at com.mysql.cj.jdbc.ClientPreparedStatement.executeUpdateInternal(ClientPreparedStatement.java:1046)
at com.mysql.cj.jdbc.ClientPreparedStatement.executeLargeUpdate(ClientPreparedStatement.java:1371)
at com.mysql.cj.jdbc.ClientPreparedStatement.executeUpdate(ClientPreparedStatement.java:1031)
at com.mchange.v2.c3p0.impl.NewProxyPreparedStatement.executeUpdate(NewProxyPreparedStatement.java:462)
at org.hibernate.engine.jdbc.internal.ResultSetReturnImpl.executeUpdate(ResultSetReturnImpl.java:197)
... 61 more

Regards

Alejandro Revilla

unread,
May 26, 2025, 6:48:37 PMMay 26
to jpos-...@googlegroups.com
Why don't you use GLSession's createCompositeAccount or createFinalAccount ?

Reply all
Reply to author
Forward
0 new messages