RecordEditForm without Configured Datasource

I am currently testing this on an Ignition 7.7.5 install, looking for a better 7.7.5 solution (or even future fix).

Overview:
When I try to open a config page (that I created) which extends RecordEditForm without first creating a datasource (that it would be able to display in a drop down) a null pointer error is thrown. As this problem occurs in the Gateway Module Hook, simply adding a datasource and trying to open the config page again doesn’t solve the problem. You can see how this would be very frustrating for a customer that doesn’t know anything about null pointer exceptions.

More Info:
When I try to create a config page that extends RecordEditForm and give its call to its super constructor a new

SRecordInstance[] ((GatewayContext) Application.get()).getPersistenceInterface().find(MySettingsRecord.META, new Object[] { Long.valueOf(0L) }) });

where

MySettingsRecord extends a PersistentRecord and contains a drop down to select a datasource

public final static LongField DatasourceId = new LongField(META, "DatasourceId", SFieldFlags.SMANDATORY).setDefault(0L); public final static ReferenceField<DatasourceRecord> Datasource = new ReferenceField<DatasourceRecord>(META, DatasourceRecord.META, "Datasource", DatasourceId);
a null pointer is exception is logged with the attached stack trace.

Creating a datasource and restarting the module is the current fix, but I wanted to bring this up as I believe there are better solutions out there. Possibly even a fix in future releases.

Short Stack Trace:
Note: WebSFServletConfigPage is the config page I am talking about in the log.

Config Error creating panel class: class com.kymera.gateway.config.pages.WebSFServletConfigPage
Caused by: java.lang.NullPointerException
at com.inductiveautomation.ignition.gateway.web.models.DirectRecordListModel.(DirectRecordListModel.java:42)
at com.inductiveautomation.ignition.gateway.web.models.CompoundRecordModel.(CompoundRecordModel.java:44)
at com.inductiveautomation.ignition.gateway.web.models.CompoundRecordModel.(CompoundRecordModel.java:39)
at com.inductiveautomation.ignition.gateway.web.components.RecordEditForm.(RecordEditForm.java:78)
at com.kymera.gateway.config.pages.WebSFServletConfigPage.(WebSFServletConfigPage.java:18)

Have you tried wrapping it in a Try: Except: statement?

Have you tried not setting a default for DatasourceId ?

As the WebSFServletConfigPage extends the RecordEditForm, the first call in the constructor has to be to the super constructor, and as this appears to be where the NullPointerException is bring thrown I don’t believe I can simply wrap it in a try catch. That is a good thing to check whenever you run into a null pointer exception though.

I’m now getting into territory that’s getting harder to fully summarize without providing a ton of source code, but the following is my best attempt at a useful summary.

By not setting a default value (but continuing to make it a mandatory field) I get the following erorrs when installing the module:

[quote]PersistenceInterface Error saving record: “[websf servlet] Enabled:true”
simpleorm.utils.SException$Validation: Field [F WebSFServletSettings.DatasourceId] must be NOT NULL
[/quote]

[quote]WebSFGatewayHook Failed to insert servlet record
simpleorm.utils.SException$Validation: Field [F WebSFServletSettings.DatasourceId] must be NOT NULL
[/quote]
I believe the definition of this field with the inclusion of “SFieldFlags.SMANDATORY” is causing this validator to then fail, which also stops the creation and insertion of the record (leading to the original error again when trying to open the config page).

Removing the mandatory flag (even though I do want it to be a mandatory field) just as an experiment and I get the following when installing the module. It too stops the creation and insertion of the record (leading to the original error again when trying to open the config page).

[quote]PersistenceInterface Error saving record: “[websf servlet] Enabled:true”
simpleorm.utils.SException$Jdbc: Executing INSERT INTO WebSFServletSettings (WebSFServletSettings_ID) VALUES (?) for [websf servlet] Enabled:true

at com.inductiveautomation.ignition.gateway.localdb.PersistenceInterfaceImpl.save(PersistenceInterfaceImpl.java:108)
at com.kymera.gateway.WebSFGatewayHook.initializeServletRecord(WebSFGatewayHook.java:232)
at com.kymera.gateway.WebSFGatewayHook.setup(WebSFGatewayHook.java:154)

Caused by: java.sql.SQLIntegrityConstraintViolationException: integrity constraint violation: foreign key no parent; “FK_WEBSFSERVLETSETTINGS_DATASOURCE” table: “WEBSFSERVLETSETTINGS”

Caused by: org.hsqldb.HsqlException: integrity constraint violation: foreign key no parent; “FK_WEBSFSERVLETSETTINGS_DATASOURCE” table: “WEBSFSERVLETSETTINGS”
[/quote]

I believe this foreign key constraint is included in the creation of the “ReferenceField” which uses the datasourceId (that no longer has a default nor is mandatory). That is handled outside of my code though, so I don’t think pursuing this much further is going to yield anything I can act upon.

I am still open to better solutions, but I did find one solution that at least ensures the user doesn’t have to restart the module after adding a datasource.
Simply creating a listener that tries to recreate the config page (and associated links) when a datasource record is added, then destroys itself on success, saves the module restart step.

Thank you for your help