Creating entities programmatically on many side in New Entity Edit Form

Hi, We have one-to-many relationship between Asset->Specifications. We are trying to create multiple specifications programmatically in the edit screen of Asset entity (New Entity). We are facing two problems.

  1. It gives error “During synchronization a new object was found through a relationship that was not marked cascade PERSIST”. Though for any saved entity, multiple specification entities are created. After adding CascadeType Persist on both side of relationship, it giver error “PK violation Error”.
  2. Another problem is after adding multiple specification, they do not appear in specification table immediately and will appear only when the screen is closed and open again.
  3. The one side of entity can not be deleted if many side entities are there. Though we have provided FK Constraint Action → Cascade on many side of relationship.
    Thanks

PS
The code we used to add specifications is as below;
listAssetTypeSpecs.forEach((l) → {
AssetSpecification assetSpec = new AssetSpecification();
assetSpec.setId(UUID.randomUUID());
assetSpec.setName(l.getName());
assetSpec.setAsset(asset);

                cc.saving(assetSpec);
            });

            dataManager.save(cc);

Hi, First two problems solved by using this code:
AssetSpecification assetSpec = metadata.create(AssetSpecification.class);
assetSpec.setName(l.getName());
assetSpec.setAsset(getEditedEntity());
AssetSpecification myi = dataContext.merge(assetSpec);
specificationsDc.getMutableItems().add(assetSpec);
If there is any better way, please guide. Also guide for third issue.
Thanks

Hi!

Programmatic creating and removing entities are described in our docs.

Please ask if you still have any questions.

Regards,
Nadezhda.

The code is correct, but it can be a bit shorter if you create the new instance through DataContext (it will be merged right away):

AssetSpecification assetSpec = dataContext.create(AssetSpecification.class);
assetSpec.setName(l.getName());
assetSpec.setAsset(getEditedEntity());
specificationsDc.getMutableItems().add(assetSpec);

This is also correct. You need to create a FK with “on delete cascade”.

1 Like

Thanks Konstantin. This has solved our problems.

Hi Konstantin,

I am running somehow in a similar problem.

After adding a child record to the parent, the child doesn’t appear in the table and will appear only when the screen is closed again (This is the same point 2 as in the first post).

First the record appears in the list. Then if I modify it with edit function, then all other records from the table disappear and only the modified record is shown in the table. Somehow the container childrenDc is reset.

This happens only if I modify the child record before committing the results. The update is triggered in this way:

  ChildComponentEdit editScreen = screenBuilders.editor(Child.class, this)
            .withScreenClass(ChildComponentEdit.class)
            .withParentDataContext(dataContext)
            .editEntity(selectedChildFromTable)
            .withListComponent(childsTable)
            .withAfterCloseListener(afterCloseEvent -> {
                if (afterCloseEvent.closedWith(StandardOutcome.COMMIT)) {
                    Child entity = afterCloseEvent.getSource().getEditedEntity();
                    entity.setParent(getEditedEntity())
                    Child merged = dataContext.merge(entity);
                    if (childrenDc.getItems().contains(merged)) {
                        childrenDc.replaceItem(merged);
                    } else {
                        childrenDc.getMutableItems().add(merged);
                    }
                }
            })
            .build()
            .show()

Parent Entity:

@Composition
@OneToMany(mappedBy = “parent”)
@OrderBy(“priorityOrder ASC”)
@OnDelete(DeletePolicy.CASCADE)
private List children;

Child Entity

@ManyToOne(fetch = FetchType.LAZY, optional = false)
@JoinColumn(name = “PAR”, nullable = false)
private Parent parent;

The ChildComponentEdit is a StandardEditScreen.

Any idea what I am doing wrong.

Thanks,
Samy

Hi Samy,
Could you attach your test project?