Hello,
I have an issue with dependentFields declared on a validator. When a dependent field is absent from request it's pulled in from the database and validated, which causes two problems:
Test case, verified on SmartClient v13.1p_2025-05-12/PowerEdition:
Database schema:
Data source:
Validators with logging:
When I create a new record I see what I expect, three validations on singular values:
but when I update only the domain field:
validateDomainAlias was called with a String value of "[alias1, alias2]", which is neither a valid single item value nor a valid representation conforming to configured multipleStorage.
I have an issue with dependentFields declared on a validator. When a dependent field is absent from request it's pulled in from the database and validated, which causes two problems:
- A potential performance issue, especially if that validator needs to execute some additional database queries, or perform external I/O - why validate it at all when the value comes straight from the database?
- When this dependent field has multipleStorage defined the validation is run on a value that looks like a result of calling ArrayList.toString
Test case, verified on SmartClient v13.1p_2025-05-12/PowerEdition:
Database schema:
Code:
CREATE TABLE test_vhosts ( id SERIAL PRIMARY KEY, domain TEXT NOT NULL, domain_aliases jsonb DEFAULT '[]'::jsonb, comment TEXT NOT NULL DEFAULT '' );
Code:
<DataSource ID="testVhostsDS" serverType="sql" tableName="test_vhosts"> <fields> <field name="id" type="sequence" hidden="true" primaryKey="true"/> <field name="domain" type="text" required="true"> <validators> <validator type="serverCustom" dependentFields="domain_aliases"> <serverObject className="pl.test.TestVhostsValidators" methodName="validateDomain"/> </validator> </validators> </field> <field name="domain_aliases" type="text" multiple="true" multipleStorage="json"> <validators> <validator type="serverCustom" dependentFields="domain"> <serverObject className="pl.test.TestVhostsValidators" methodName="validateDomainAlias"/> </validator> </validators> </field> <field name="comment" type="text" defaultValue=""/> </fields> </DataSource>
Code:
package pl.test; import com.isomorphic.datasource.DataSource; import com.isomorphic.datasource.Validator; import com.isomorphic.log.Logger; import java.util.Map; public class TestVhostsValidators { private final Logger log = new Logger(this); public boolean validateDomain(Object value, Validator validator, String fieldName, Map<?, ?> record, DataSource ds) { log.info("Validating domain: " + toLogLine(value, record)); return true; } public boolean validateDomainAlias(Object value, Validator validator, String fieldName, Map<?, ?> record, DataSource ds) { log.info("Validating domain alias: " + toLogLine(value, record)); return true; } private String toLogLine(Object value, Map<?, ?> record) { return "value=%s (type=%s) record=%s (domain_aliases type=%s)" .formatted(String.valueOf(value), className(value), record.toString(), className(record.get("domain_aliases"))); } private String className(Object value) { return value == null ? "null" : value.getClass().getSimpleName(); } }
Code:
testVhostsDS.addData({domain: "test1", domain_aliases: ["alias1", "alias2"]}, (dsResponse, data) => console.log(data)) // Validating domain alias: value=alias1 (type=String) record={domain_aliases=[alias1, alias2], domain=test1} (domain_aliases type=ArrayList) // Validating domain alias: value=alias2 (type=String) record={domain_aliases=[alias1, alias2], domain=test1} (domain_aliases type=ArrayList) // Validating domain: value=test1 (type=String) record={domain_aliases=[alias1, alias2], domain=test1} (domain_aliases type=ArrayList)
Code:
testVhostsDS.updateData({id: 1, domain: "test2"}, (dsResponse, data) => console.log(data)) // Validating domain alias: value=[alias1, alias2] (type=String) record={domain_aliases=[alias1, alias2], domain=test2, id=2} (domain_aliases type=ArrayList) // Validating domain: value=test2 (type=String) record={domain_aliases=[alias1, alias2], domain=test2, id=2} (domain_aliases type=ArrayList)
Comment