How to properly inherit entities and their screens

Hi,

I’m trying to implement inherited entities and would like to reuse the editor/browser screens as much as possible for the inherited entities. I’m not sure how to do this.

Basically, I have a number of lists with different types of assets: hardware components, software tools, keys etc. They all have some fields and functional behavior in common, hence the inheritance strategy.

For the base class, containing the shared fields and functionality, I have created a browser and editor screen. For the extended entities (each holding entity-specific fields and implement specific functionality) I would like to reuse the browser and editor.

For the browser this was possible by adding a collection datasource and override the datasource property on the table.

For the editor however it doesn’t work as adding the entity-specific datasource and setting the datasource on the corresponding field components (I’m not using a fieldgroup) results in an editor that shows up empty and after editing a field always clears the input.

It seems that the fields in the editor remain linked to the base entity rather than the extended entity.

I’m probably doing this the wrong way. What direction am I supposed to solve this?

Thanks for helping me out here.

Addition: when overriding the ‘datasource’ property of the window definition it works on the editor as well. So I guess, this is a way to do it. But is it the best way?

One question I still have is whether it can be avoided to override all the datasource properties on the individual field components (not using field group)?

Could you share some code of your extended entities and screens? When you extend screens, do you override the entity type for datasources?

Hi Konstantin,
Here is my base editor screen definition:

<i><?</i><b>xml version=</b><b>"1.0" </b><b>encoding=</b><b>"UTF-8" </b><b>standalone=</b><b>"no"</b><i>?></i>
<<b>window </b><b>xmlns=</b><b>"[url=http://schemas.haulmont.com/cuba/window.xsd]http://schemas.haulmont.com/cuba/window.xsd"[/url];</b>
<b>        </b><b>caption=</b><b>"msg://editorCaption"</b>
<b>        </b><b>class=</b><b>"com.axxemble.base27.web.asset.AssetEdit"</b>
<b>        </b><b>datasource=</b><b>"assetDs"</b>
<b>        </b><b>focusComponent=</b><b>"name"</b>
<b>        </b><b>messagesPack=</b><b>"com.axxemble.base27.web.asset"</b>> 
    <<b>dsContext</b>> 
        <<b>datasource </b><b>id=</b><b>"assetDs"</b>
<b>                    </b><b>class=</b><b>"com.axxemble.base27.entity.Asset"</b>
<b>                    </b><b>view=</b><b>"asset-view"</b>> 
            <<b>collectionDatasource </b><b>id=</b><b>"commentsDs"</b>
<b>                                  </b><b>property=</b><b>"comments"</b>/> 
            <<b>collectionDatasource </b><b>id=</b><b>"filesDs"</b>
<b>                                  </b><b>property=</b><b>"files"</b>/> 
        </<b>datasource</b>> 
        <<b>collectionDatasource </b><b>id=</b><b>"staffsDs"</b>
<b>                              </b><b>class=</b><b>"com.axxemble.base27.entity.Staff"</b>
<b>                              </b><b>view=</b><b>"staff-view"</b>> 
            <<b>query</b>> 
                <!&#91;CDATA&#91;select e from base$Staff e where e.active = true&#93;&#93;> 
            </<b>query</b>> 
        </<b>collectionDatasource</b>> 
    </<b>dsContext</b>> 
    <<b>dialogMode </b><b>height=</b><b>"600"</b>
<b>                </b><b>width=</b><b>"800"</b>/> 
    <<b>layout </b><b>expand=</b><b>"allTabs"</b>
<b>            </b><b>spacing=</b><b>"true"</b>> 
        <<b>tabSheet </b><b>id=</b><b>"allTabs"</b>> 
            <<b>tab </b><b>id=</b><b>"tabContent"</b>
<b>                 </b><b>caption=</b><b>"msg://editorCaption"</b>
<b>                 </b><b>margin=</b><b>"true,false,false,false"</b>> 
                <<b>scrollBox </b><b>id=</b><b>"contentScroll"</b>
<b>                           </b><b>height=</b><b>"100%"</b>> 
                    <<b>grid </b><b>id=</b><b>"propertyGrid"</b>
<b>                          </b><b>spacing=</b><b>"true"</b>
<b>                          </b><b>width=</b><b>"100%"</b>> 
                        <<b>columns</b>> 
                            <<b>column</b>/> 
                            <<b>column </b><b>flex=</b><b>"1.0"</b>/> 
                        </<b>columns</b>> 
                        <<b>rows</b>> 
                            <<b>row </b><b>id=</b><b>"codeRow"</b>> 
                                <<b>label </b><b>stylename=</b><b>"defLabel"</b>
<b>                                       </b><b>value=</b><b>"msg://com.axxemble.base27.entity/Asset.code"</b>
<b>                                       </b><b>width=</b><b>"250px"</b>/> 
                                <<b>hbox </b><b>id=</b><b>"codeControl"</b>> 
                                    <<b>textField </b><b>id=</b><b>"code"</b>
<b>                                               </b><b>caption=</b><b>"msg://com.axxemble.base27.entity/Asset.code"</b>
<b>                                               </b><b>datasource=</b><b>"assetDs"</b>
<b>                                               </b><b>description=</b><b>"msg://Tip.Code"</b>
<b>                                               </b><b>property=</b><b>"code"</b>
<b>                                               </b><b>enable=</b><b>"false"</b>
<b>                                               </b><b>width=</b><b>"250px"</b>/> 
                                    <<b>label </b><b>width=</b><b>"5px"</b>/> 
                                    <<b>button </b><b>id=</b><b>"editCode"</b>
<b>                                            </b><b>caption=</b><b>"msg://EditCode"</b>
<b>                                            </b><b>invoke=</b><b>"onEditCodeClick"</b>/> 
                                </<b>hbox</b>> 
                            </<b>row</b>> 
                        <<b>row </b><b>id=</b><b>"nameRow"</b>> 
                <<b>label </b><b>stylename=</b><b>"defLabel"</b>
<b>                       </b><b>value=</b><b>"msg://com.axxemble.base27.entity/Asset.name"</b>
<b>                       </b><b>width=</b><b>"250px"</b>/> 
                <<b>textField </b><b>id=</b><b>"name"</b>
<b>                           </b><b>caption=</b><b>"msg://com.axxemble.base27.entity/Asset.name"</b>
<b>                           </b><b>datasource=</b><b>"assetDs"</b>
<b>                           </b><b>description=</b><b>"msg://Tip.Name"</b>
<b>                           </b><b>property=</b><b>"name"</b>
<b>                           </b><b>required=</b><b>"true"</b>
<b>                           </b><b>width=</b><b>"250px"</b>/> 
            </<b>row</b>> 
            <<b>row </b><b>id=</b><b>"descRow"</b>> 
                <<b>label </b><b>stylename=</b><b>"defLabel"</b>
<b>                       </b><b>value=</b><b>"msg://com.axxemble.base27.entity/Asset.description"</b>/> 
                <<b>richTextArea </b><b>id=</b><b>"description"</b>
<b>                              </b><b>caption=</b><b>"msg://com.axxemble.base27.entity/Asset.description"</b>
<b>                              </b><b>datasource=</b><b>"assetDs"</b>
<b>                              </b><b>description=</b><b>"msg://Tip.Description"</b>
<b>                              </b><b>height=</b><b>"200px"</b>
<b>                              </b><b>property=</b><b>"description"</b>
<b>                              </b><b>width=</b><b>"95%"</b>/> 
            </<b>row</b>> 
            <<b>row </b><b>id=</b><b>"ownerRow"</b>> 
                <<b>label </b><b>stylename=</b><b>"defLabel"</b>
<b>                       </b><b>value=</b><b>"msg://com.axxemble.base27.entity/Asset.owner"</b>/> 
                <<b>lookupField </b><b>id=</b><b>"owner"</b>
<b>                             </b><b>caption=</b><b>"msg://com.axxemble.base27.entity/Asset.owner"</b>
<b>                             </b><b>datasource=</b><b>"assetDs"</b>
<b>                             </b><b>description=</b><b>"msg://Tip.Owner"</b>
<b>                             </b><b>optionsDatasource=</b><b>"staffsDs"</b>
<b>                             </b><b>property=</b><b>"owner"</b>
<b>                             </b><b>width=</b><b>"250px"</b>/> 
            </<b>row</b>> 
            <i><!-- 5 optional fields for the extended entities --></i>
<i>            </i><<b>row </b><b>id=</b><b>"addFieldRow1"</b>/> 
            <<b>row </b><b>id=</b><b>"addFieldRow2"</b>/> 
            <<b>row </b><b>id=</b><b>"addFieldRow3"</b>/> 
            <<b>row </b><b>id=</b><b>"addFieldRow4"</b>/> 
            <<b>row </b><b>id=</b><b>"addFieldRow5"</b>/> 
            <<b>row </b><b>id=</b><b>"commentsRow"</b>> 
                <<b>label </b><b>stylename=</b><b>"defLabel"</b>
<b>                       </b><b>value=</b><b>"msg://com.axxemble.base27.entity/Asset.comments"</b>/> 
                <<b>vbox </b><b>id=</b><b>"commentsBox"</b>> 
                    <<b>table </b><b>id=</b><b>"commentsTable"</b>
<b>                           </b><b>height=</b><b>"AUTO"</b>
<b>                           </b><b>width=</b><b>"95%"</b>> 
                        <<b>actions</b>> 
                            <<b>action </b><b>id=</b><b>"create"</b>/> 
                        </<b>actions</b>> 
                        <<b>columns</b>> 
                            <<b>column </b><b>id=</b><b>"updateTs"</b>
<b>                                    </b><b>caption=</b><b>"msg://Date"</b>
<b>                                    </b><b>width=</b><b>"150px"</b>/> 
                            <<b>column </b><b>id=</b><b>"createdBy"</b>
<b>                                    </b><b>caption=</b><b>"msg://Author"</b>
<b>                                    </b><b>width=</b><b>"150px"</b>/> 
                            <<b>column </b><b>id=</b><b>"comment"</b>/> 
                        </<b>columns</b>> 
                        <<b>rows </b><b>datasource=</b><b>"commentsDs"</b>/> 
                    </<b>table</b>> 
                    <<b>linkButton </b><b>action=</b><b>"commentsTable.create"</b>
<b>                                </b><b>caption=</b><b>""</b>
<b>                                </b><b>icon=</b><b>"font-icon:PLUS"</b>/> 
                </<b>vbox</b>> 
            </<b>row</b>> 
        </<b>rows</b>> 
        </<b>grid</b>> 
        </<b>scrollBox</b>> 
        </<b>tab</b>> 
        <<b>tab </b><b>id=</b><b>"tabFiles"</b>
<b>             </b><b>caption=</b><b>"msg://tab.Files"</b>
<b>             </b><b>expand=</b><b>"sysFileTable"</b>
<b>             </b><b>margin=</b><b>"true,false,false,false"</b>> 
            <<b>label </b><b>icon=</b><b>"font-icon:INFO_CIRCLE"</b>
<b>                   </b><b>stylename=</b><b>"infoTip"</b>
<b>                   </b><b>value=</b><b>"msg://Intro.Files"</b>/> 
            <<b>table </b><b>id=</b><b>"sysFileTable"</b>
<b>                   </b><b>width=</b><b>"100%"</b>> 
                <<b>actions</b>> 
                    <<b>action </b><b>id=</b><b>"create"</b>/> 
                    <<b>action </b><b>id=</b><b>"edit"</b>/> 
                    <<b>action </b><b>id=</b><b>"remove"</b>/> 
                </<b>actions</b>> 
                <<b>columns</b>> 
                    <<b>column </b><b>id=</b><b>"fileFile"</b>/> 
                    <<b>column </b><b>id=</b><b>"fileVersion"</b>/> 
                    <<b>column </b><b>id=</b><b>"updateTs"</b>/> 
                    <<b>column </b><b>id=</b><b>"updatedBy"</b>/> 
                    <<b>column </b><b>id=</b><b>"fileRemarks"</b>/> 
                </<b>columns</b>> 
                <<b>rows </b><b>datasource=</b><b>"filesDs"</b>/> 
                <<b>buttonsPanel</b>> 
                    <<b>button </b><b>action=</b><b>"sysFileTable.create"</b>
<b>                            </b><b>caption=</b><b>""</b>/> 
                    <<b>button </b><b>action=</b><b>"sysFileTable.edit"</b>/> 
                    <<b>button </b><b>action=</b><b>"sysFileTable.remove"</b>/> 
                </<b>buttonsPanel</b>> 
            </<b>table</b>> 
        </<b>tab</b>> 
        </<b>tabSheet</b>> 
        <<b>frame </b><b>id=</b><b>"windowActions"</b>
<b>               </b><b>screen=</b><b>"editWindowActions"</b>/> 
<i><!--        <buttonsPanel id="buttonRow"></i>
<i>            <button id="btnSave"</i>
<i>                    caption="msg://Save"</i>
<i>                    invoke="onBtnSaveClick"></button></i>
<i>            <button id="btnCancel"</i>
<i>                    caption="msg://Cancel"</i>
<i>                    invoke="onBtnCancelClick"></button></i>
<i>        </buttonsPanel>--></i>
<i>    </i></<b>layout</b>> 
</<b>window</b>> 

And here is the extended editor screen:
```
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<window xmlns=http://schemas.haulmont.com/cuba/window.xsd”;
class=“com.axxemble.base27.web.hardware.HardwareEdit”
datasource=“hardwareDs”
extends=“com/axxemble/base27/web/asset/asset-edit.xml”
messagesPack=“com.axxemble.base27.web.hardware”>
<dsContext>
<datasource id=“hardwareDs”
class=“com.axxemble.base27.entity.Hardware”
view=“hardware-view”>
<collectionDatasource id=“hwCommentsDs”
property=“comments”/>
<collectionDatasource id=“hwFilesDs”
property=“files”/>
</datasource>
</dsContext>
<layout>
<tabSheet id=“allTabs”>
<tab id=“tabContent”>
<scrollBox id=“contentScroll”>
<grid id=“propertyGrid”>
<rows>
<row id=“codeRow”>
<hbox id=“codeControl”>
<textField id=“code”
datasource=“hardwareDs”/>
</hbox>
</row>
<row id=“nameRow”>
<textField id=“name”
datasource=“hardwareDs”/>
</row>
<row id=“descRow”>
<richTextArea id=“description”
datasource=“hardwareDs”/>
</row>
<row id=“ownerRow”>
<lookupField id=“owner”
datasource=“hardwareDs”/>
</row>
<row id=“addFieldRow1”>
<label stylename=“defLabel”
value=“msg://com.axxemble.base27.entity/Hardware.hwType”/>
<lookupField id=“optLikelihood”
caption=“msg://com.axxemble.base27.entity/Hardware.hwType”
datasource=“hardwareDs”
description=“msg://Tip.Type”
property=“hwType”
required=“true”
width=“250px”/>
</row>
<row id=“commentsRow”>
<vbox id=“commentsBox”>
<table id=“commentsTable”>
<rows datasource=“hwCommentsDs”/>
</table>
</vbox>
</row>
</rows>
</grid>
</scrollBox>
</tab>
<tab id=“tabFiles”>
<table id=“sysFileTable”>
<rows datasource=“hwFilesDs”/>
</table>
</tab>
</tabSheet>
</layout>
</window>

This is actually working but it's a pity that I need to set the datasource on all field components for the extended screen. 
Not sure what you mean by overriding the entity type for datasource. I do set it on the extended screen in the <window> tag if that's what you mean.

Sorry for the mixup in styling.

Hmmm, I think I found the answer to my main question, see code below. By modifying the XML descriptor in IDE (instead of studio) I was able to override the assetDs datasource in such a way that I do not have to override the datasource properties on the individual field controls.

<i><?</i><b>xml version=</b><b>"1.0" </b><b>encoding=</b><b>"UTF-8" </b><b>standalone=</b><b>"no"</b><i>?>
</i><<b>window </b><b>xmlns=</b><b>"http://schemas.haulmont.com/cuba/window.xsd"
</b><b>        </b><b>class=</b><b>"com.axxemble.base27.web.hardware.HardwareEdit"
</b><b>        </b><b>datasource=</b><b>"assetDs"
</b><b>        </b><b>extends=</b><b>"com/axxemble/base27/web/asset/asset-edit.xml"
</b><b>        </b><b>messagesPack=</b><b>"com.axxemble.base27.web.hardware"</b>>
    <<b>dsContext</b>>
        <<b>datasource </b><b>id=</b><b>"assetDs"
</b><b>                    </b><b>class=</b><b>"com.axxemble.base27.entity.Hardware"
</b><b>                    </b><b>view=</b><b>"hardware-view"</b>>
        </<b>datasource</b>>
    </<b>dsContext</b>>
    <<b>layout</b>>
        <<b>tabSheet </b><b>id=</b><b>"allTabs"</b>>
            <<b>tab </b><b>id=</b><b>"tabContent"</b>>
                <<b>scrollBox </b><b>id=</b><b>"contentScroll"</b>>
                    <<b>grid </b><b>id=</b><b>"propertyGrid"</b>>
                        <<b>rows</b>>
                            <<b>row </b><b>id=</b><b>"addFieldRow1"</b>>
                                <<b>label </b><b>stylename=</b><b>"defLabel"
</b><b>                                       </b><b>value=</b><b>"msg://com.axxemble.base27.entity/Hardware.hwType"</b>/>
                                <<b>lookupField </b><b>caption=</b><b>"msg://com.axxemble.base27.entity/Hardware.hwType"
</b><b>                                             </b><b>datasource=</b><b>"assetDs"
</b><b>                                             </b><b>description=</b><b>"msg://Tip.Type"
</b><b>                                             </b><b>property=</b><b>"hwType"
</b><b>                                             </b><b>required=</b><b>"true"
</b><b>                                             </b><b>width=</b><b>"250px"</b>/>
                            </<b>row</b>>
                            <<b>row </b><b>id=</b><b>"addFieldRow2"</b>>
                                <<b>label </b><b>stylename=</b><b>"defLabel"
</b><b>                                       </b><b>value=</b><b>"msg://com.axxemble.base27.entity/Hardware.manufacturer"</b>/>
                                <<b>textField </b><b>datasource=</b><b>"assetDs"
</b><b>                                           </b><b>caption=</b><b>"msg://com.axxemble.base27.entity/Hardware.manufacturer"
</b><b>                                           </b><b>description=</b><b>"msg://Tip.Manufacturer"
</b><b>                                           </b><b>property=</b><b>"manufacturer"
</b><b>                                           </b><b>width=</b><b>"250px"</b>/>
                            </<b>row</b>>
                            <<b>row </b><b>id=</b><b>"addFieldRow3"</b>>
                                <<b>label </b><b>stylename=</b><b>"defLabel"
</b><b>                                       </b><b>value=</b><b>"msg://com.axxemble.base27.entity/Hardware.model"</b>/>
                                <<b>textField </b><b>datasource=</b><b>"assetDs"
</b><b>                                           </b><b>description=</b><b>"msg://Tip.Model"
</b><b>                                           </b><b>property=</b><b>"model"
</b><b>                                           </b><b>width=</b><b>"250px"</b>/>
                            </<b>row</b>>
                            <<b>row </b><b>id=</b><b>"addFieldRow4"</b>>
                                <<b>label </b><b>stylename=</b><b>"defLabel"
</b><b>                                       </b><b>value=</b><b>"msg://com.axxemble.base27.entity/Hardware.serialNumber"</b>/>
                                <<b>textField </b><b>datasource=</b><b>"assetDs"
</b><b>                                           </b><b>property=</b><b>"serialNumber"
</b><b>                                           </b><b>description=</b><b>"msg://Tip.SerialNumber"
</b><b>                                           </b><b>width=</b><b>"250px"</b>/>
                            </<b>row</b>>
                            <<b>row </b><b>id=</b><b>"addFieldRow5"</b>>
                                <<b>label </b><b>stylename=</b><b>"defLabel"
</b><b>                                       </b><b>value=</b><b>"msg://com.axxemble.base27.entity/Hardware.purchaseDate"</b>/>
                                <<b>dateField </b><b>datasource=</b><b>"assetDs"
</b><b>                                           </b><b>property=</b><b>"purchaseDate"
</b><b>                                           </b><b>description=</b><b>"msg://Tip.PurchaseDate"
</b><b>                                           </b><b>width=</b><b>"250px"</b>/>
                            </<b>row</b>>
                        </<b>rows</b>>
                    </<b>grid</b>>
                </<b>scrollBox</b>>
            </<b>tab</b>>
            <<b>tab </b><b>id=</b><b>"exchange" </b><b>visible=</b><b>"true"</b>/> <i><!-- Use the exchange functionality on hardware -->
</i><i>        </i></<b>tabSheet</b>>
    </<b>layout</b>>
</<b>window</b>>

I’ve meant exactly this - to set concrete entity (Hardware) as entity type (class attribute) for existing datasource (assetDs).