Problem with transaction when last statement is throwing sql-exception

I have a problem when I try to manipulate multiple entities in one single transaction.
The model is a self referenced entity with a parent-child structure.

When I want to delete an entity within the hierarchy I have to rebind the childs to the parent of the of the actual entity.
It is all done in a service using the TransactionalDataManager.
I create a new transaction, load all the childs from the given entity and rebind the Parent-Id to the parent of the current. Then I delete the current entity.

Now, when the current entity can not be deleted, because there is a foreign key database constraint, the save-operations of the child-entities in the for-loop are not being rolled back.
In my understanding the operation should be rolled back, when the last operation is not going through?
I am using an oracleDB, and the call to the service is done from within a remove-operation of a hierarchical table. I do the complete remove-operation in the service.

public class LagerplatzDeleteServiceBean implements LagerplatzDeleteService {

        private TransactionalDataManager transactionalDataManager;

        public void LinkChildsToRoot(JtLagerplatz lagerplatz){

            LoadContext<JtLagerplatz> loadContextLagerplatz
                    = LoadContext.create(JtLagerplatz.class).setQuery(
                    LoadContext.createQuery("select p from roman_JtLagerplatz p where p.idLagerplatzParent = :idLagerplatz" )

            // run all in one transaction
            Transaction tx = transactionalDataManager.transactions().get();
            try {
                // load list of child Entities
                List<JtLagerplatz> lRet = transactionalDataManager.loadList(loadContextLagerplatz);

                JtLagerplatz lagParent = lagerplatz.getIdLagerplatzParent();

                // manipulate dhild entities
                for (JtLagerplatz l : lRet) {
                // delete entity

            } finally {


The calling action:

    public void onJtLagerplatzesTable1Remove(Action.ActionPerformedEvent event) {
        JtLagerplatz curr = jtLagerplatzesHierarchicalDc.getItem();

                .withCaption("Löschen des Lagerplatzes")
                .withMessage("Untergeordnete Lagerplätze werden nach oben verlinkt.")
                        new DialogAction(DialogAction.Type.YES)
                                .withHandler(e ->  {
                                }), // execute action
                        new DialogAction(DialogAction.Type.NO)

What am I doing wrong?

Regards Manfred

Your code looks correct, it should work.

It would be great if you could reproduce the problem on a small demo project, to make sure that the case is isolated from specifics of your project.
Then CUBA team will be able to investigate this project.

I will try to set up the demo in the near future and send it to you.


I created a testproject. It needs an external datastore in an oracle. Scripts are included.
I hope I did not forget anything and it helps to find the problem. (79,2 KB) .


Hi @manfred_p,

Entities are stored in an additional Oracle datastore, but the sample code creates a transaction in the main CUBA store:


-> so each executed in a separate transaction on the additional store. TransactionalDataManager creates a transaction for the store if it doesn’t exist.

In order to fix the error, you need to create a transaction for a corresponding store using:

Transaction tx = transactionalDataManager.transactions().get("cuba_test")

From the JavaDoc:

     * Creates a new transaction in the main data store if there is no one at the moment.
     * @see #get(String)
    Transaction get();

     * Creates a new transaction if there is no one at the moment.
     * <p>If a transaction exists, joins the current transaction. In this case:
     * <ul>
     *     <li>Subsequent invocation of {@link Transaction#commit()} does not affect current transaction.</li>
     *     <li>If {@link Transaction#end()} is called without previous {@link Transaction#commit()}, current
     *     transaction is marked as rollback-only, so any attempt to commit the surrounding {@link Transaction} will
     *     throw an exception.</li>
     * </ul>
     * @param storeName data store name
     * @return object to control the transaction
    Transaction get(String storeName);
1 Like

Hello Andrey,

thanks for the help. It works!