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