Hello, I am in the process of evaluating Cuba platform for a rather small business application (CRM application, managing trainers, clients and seminars in a rather flexible way) that needs to be as user friendly as possible (which means as few clicks, keystrokes and page navigations as possible).
In order to achieve this, I often need to create nested entities on behalf of the user in one step on a single page, so he does not need to navigate between pages to create single entities that need to be linked later.
So when I try to create an entity “Participant”, that links to an entity “Person” (which also links to an entity “Address”) using a “Participant” master detail screen, creating new entities Address and Person in this process, at the moment, the Participant->Person->Address object graph ist persisted, an exception occurrs:
IllegalStateException: During synchronization a new object was found through a relationship that was not marked cascade PERSIST
I know, that probem was reported by other users already, but they worked with a previous 6.x cuba framework, while I am using 7.0.5. I cannot find recent relevant documentation how to solve this problem.
I attached corresponding screen code and XML. Hint: Teilnehmer = Participant
you are right, there was indeed some problem with my domain model. I managed to correct that issue by adding the property cascade = CascadeType.PERSIST to the corresponding annotation, i.e.
where adresse is my navigation property to the related Address entity within an outer Person entity.
Of course, I still don’t know, if this is the best way to resolve this issue or whether there are alternatives that might be better under certain circumstances. Older posts mentioned adding newly created entities to the datacontext, commitcontext or using nested datacollections, which I was not able to implement properly.
Would these options still be viable?
This error usually occurs when you create entity A, set it as attribute of entity B, and save only entity B. CascadeType.PERSIST solves the issue on the ORM level, but it’s not recommended in CUBA as sometimes leads to unexpected behavior. Better make sure entity A is saved too. Just create it via DataContext: dataContext.create(A.class);, then DataContext will commit it together with all changed entities of the screen.
The sample model are three classes in composition like this:
Have a service in middleware named PersistDataServiceBean, that have a method for persist test data on Entities A, B and C. For call it, I create a screen named “PersisitDataTestScreen” with a button.
Please can u tell me how can I do the persistence in cascade like JPA without the annotation cascade = CascadeType.PERSIST?
In function of your sample code, my mistake was that I adding the new EntityB object to the bidirectional relationship attribute of EntityA (bEntities).
CommitContext cc = new CommitContext();
EntityA entityA = dataManager.create(EntityA.class);
entityA.setName("ENTITY A1");
cc.addInstanceToCommit(entityA);
EntityB entityB1 = dataManager.create(EntityB.class);
entityB1.setNumber(1);
entityB1.setEntityA(entityA);
cc.addInstanceToCommit(entityB1);
// THE MISTAKE.
// THIS THROW THE EXCEPTION: IllegalStateException: During synchronization a new object was found through a relationship that was not marked cascade PERSIST
entityA.getBEntities().add(entityB1);
// ...
dataManager.commit(cc);
Just with “entityB1.setEntityA(entityA)” and committing both entities, it works.