5.8.2.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 one-to-one to a platform entity (User
). When a new employee instance is being created, a new user instance should be created as well.
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.