Validation error creating obs with class Text

Hello,

I am trying to create observations for a concept of class Text, from UTF-8 encoded csv files using the openmrs API. Some data are not imported, generating this error:

org.openmrs.api.APIException: ‘obs id is null’ failed to validate with reason: valueText: This value exceeds the maximum length of {0} permitted for this field.

The length of the texts that fail are however pretty small around 50-200 characters so it should not be a problem.

Could you please advise, as to what might be the issue ? Here is the code to create the obs, where text is the value read from the file through an InputStreamReader:

                    Concept c = Context.getConceptService().getConcept(163476);
		Obs strObs = new Obs(p, c, new Date(), Context.getLocationService().getLocation(1));
		try {
			strObs.setValueText(text);					
			Context.getObsService().saveObs(strObs, "new entry");
		} catch(Exception e) {
			e.printStackTrave();
		}

thanks

Looks like a bug, can you create a JIRA ticket? Also, message parameters are not replaced.

1 Like

ok thanks I will. However, I find it strange that there is a bug there, since I suppose other modules like the htmlformentry module probably use the API as well…

I have the same problem with the REST API : when submitting an observation having a text of about 1600 characters the error appear. I searched the error message in the github code repository and found a class named ObsValidator having a declaration like this : public final static int VALUE_TEXT_MAX_LENGTH = 1000; and on line 204 the length of the observation text is compared to this VALUE_TEXT_MAX_LENGTH…

if (dt.isText() && obs.getValueText() != null && obs.getValueText().length() > VALUE_TEXT_MAX_LENGTH) {//...

This does not seems to make sense compared to the database field which allows 65536 characters in my setup (i did not changed the field) It would probably be better to check at the database level or to have the same limit…

@hegp, you are correct. This is definitely a bug. It appears someone arbitrarily chose a length. It should match the database constraint. Please file a bug in the TRUNK project for this.

IMHO the length should be specified at Hibernate mapping level. However we can keep the custom validator provided it reads the length from Hibernate. Another option is to remove the custom validation and leave it to Hibernate.

The best solution would specify the length of the attribute in one place (presumably in Hibernate) and still allow for validation before persisting the data. Given our separation between DAO and service layers, it may be hard to come up with a clean solution (e.g., an interface through which the service layer could retrieve the attribute length).

If forced to compromise, I would think a “correct” (matching) duplicate length in the validator would be preferable to no check in the validator, since (1) the length of this attribute is not changing and (2) clients don’t get a potentially cryptic or poorly timed error storing something that passed validation.

There is already a validateFieldLengths method in ValidateUtil that reads maximum length from Hibernate. Many validators use it, including ObsValidator but valueText property is not included. The custom validation should be removed and the field added to validateFieldLengths.

	ValidateUtil.validateFieldLengths(errors, obj.getClass(), "accessionNumber", "valueModifier", "valueComplex",
	    "comment", "voidReason");