5.8.3.3. Using initNewItem Method

Initial values can also be defined in the initNewItem() method of the screen controller of the created entity.

Assume we have the following task: a project has an Employee entity that should be linked to a platform entity (User). When a new employee instance is being created, a new user instance should be created as well.

init values recipe 2

To achieve this, we declare the data source for the employee instance and the nested data source for the linked user in the employee edit screen XML descriptor:

<dsContext>
    <datasource id="employeeDs"
                class="com.haulmont.sample.entity.Employee"
                view="employee-edit">
        <datasource id="userDs"
                    property="user"/>
    </datasource>
</dsContext>

In the employee edit screen controller, we declare:

@Inject
private Metadata metadata;

private Group defaultGroup;
private Role defaultRole;

@Override
protected void initNewItem(Employee item) {
    User user = metadata.create(User.class);
    user.setGroup(defaultGroup);
    final UserRole userRole = metadata.create(UserRole.class);
    userRole.setUser(user);
    userRole.setRole(defaultRole);
    getDsContext().addBeforeCommitListener(context -> {
        context.getCommitInstances().add(userRole);
    });
    item.setUser(user);
}

Here, in the initNewItem() method, the new User instance is created and assigned the defaultGroup. Association with the defaultRole is set up using the new instance of UserRole entity. To save this relationship to the DB during screen commit the UserRole instance is added to the saved entities collection in the beforeCommit() method of DsContext.CommitListener.

The new instance of User is assigned to the corresponding attribute of the edited Employee entity and is thus included in the nested data source userDs. This gives us an opportunity to edit necessary user attributes in the employee screen and also leads to automatic saving of the user instance in the same transaction with the other entities when the screen is committed.