Master Detail Screen - Programmatic Entity Creation?

Am wondering if it is possible to call the create function of a master detail screen?

I am trying to basically duplicate an entity. Something like follows:

protected CreateAction<Plan> tableCreate;

    protected void onDuplicatePlanButtonClick(Button.ClickEvent event) {
       tableCreate.setNewEntitySupplier(() -> {
           Plan plan = metadata.create(Plan.class);
           plan.setName("some name");
           return plan;

Of course, I am getting the “No such screen error” as there is no edit screen.

Is there any way to do this in a master detail type screen?


CreateAction in master-detail screen is assigned a special handler, see MasterDetailScreen#initBrowseCreateAction. That’s why it works but your call to execute() doesn’t. But you can call its actionPerform() method, so the correct modified handler will be invoked.

The following solution works for me:

public class ProductBrowse extends MasterDetailScreen<Product> {

    private CreateAction<Product> tableCreate;
    private GroupTable<Product> table;

    private Product prototype;

    public void onDuplicateBtnClick(Button.ClickEvent event) {
        prototype = table.getSingleSelected();
        try {
        } finally {
            prototype = null;

    public void onInitEntity(InitEntityEvent<Product> event) {
        if (prototype != null) {

On “Duplicate” click, I save the currently selected in the table entity as a prototype, and then call action’s actionPerform().
The prototype is used it in the standard InitEntityEvent handler to initialize the new entity instance.

Thanks Konstantin, works great. I was scratching my head on that one!

You wouldn’t happen to know how to also init one-to-many entities through this process? Specifically to avoid the new-entity commit context error?

e.g. say we were trying to duplicate an invoice with all the invoice lines with this type of structure

 <instance id="invoiceDc"
              class="" view="plan-view">
        <loader id="invoiceDl"/>
        <collection id="invoiceLinesDc" property="lines">

Or do I have to create a before commit listener?

In the same InitEntityEvent handler, something like this:

Invoice invoice = event.getEntity();
invoice.setLines(new ArrayList());

If you copy lines from another instance, don’t forget to change the reference to invoice in them.

Ah yes - that is what I was doing.

But upon save was getting the “On trying to persist a new entity was found that was not marked cascade persist” error. It also said I could add the new entities to the DataContext which I am not sure how to do - or was wondering if it could be done in the screen class itself…
I was trying to figure out how to get around it without having to create a ‘before insert’ listener. But I have just created one now.

Cheers :smiley:

Yes, try to create your Line entities using DataContext.create() method. See the docs: DataContext.

Awesome, thanks! Have always wondered how to do that…

On another note… I feel like the DataContext doc could do with a bit of an overhaul/update. Doesn’t describe the create method either.