MAXLEN error on saving %Persistent class

Hi,

When we define a %String property, and don't mention any MAXLEN, by default it uses 50 as defined in class %Library.String.

As a result, when we try to save data more than 50 characters, it fails with below error.

ERROR #7201: Datatype value 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX' length longer than MAXLEN allowed of 50

This is very challenging when we parse data and tries to store it in SDA3 structure, because in many places its always set to 50, which is not enough.

We have been fighting a lot to avoid MAXLEN error in various scenarios and in various part of the products over a long period of times.

The general solution we have been opting so far is, whenever we encounter this error, we make that string property to use MAXLEN=””.

Now, this is a kind of hit and trial method, and exhaustive in order to change so many properties in SDA3 structure.

What if we persists this class %Library.String in our product git, with below code change.

I know it is not recommended at all to change any library class, but without this there is no other solution.

We just need to be cautious about HSF upgrade, and make sure we take the latest and check in to our git with the below change all the time.
 
Benefit: WE WILL NEVER ENCOUNTER MAXLEN ERROR
 
Class: %Library.String
 
Currently it is:

/// The maximum number of characters the string can contain.
Parameter MAXLEN As INTEGER = 50;
 
We change it to:

/// The maximum number of characters the string can contain.
Parameter MAXLEN As INTEGER;

*** Do you see any drawback or issues with this? Can there be any other impact due to this?

Answers

*** Do you see any drawback or issues with this? Can there be any other impact due to this?

This is absolutely not a recommended approach.

Here's how you can do it.

  1. Create your own class MyString that extends %String and specifies MAXLEN parameter (I recommend 5000 or 10000, but something specific in any case).
  2. Use %Dictionary package to iterate over all your persistent classes. In there:
    • open each class
    • iterate over its properties
    • change %String type if found to MyString
    • save class
  3. Recompile modified classes.

Why dont you just do 

Property Abc as %String (Maxlen = 5000)

or use %Text

Setting MAXLEN="" or MAXLEN=5000 absolutely resolves the issue related to that specific property. But what about other potential huge list of properties within SDA3 structure?

Please read my whole notes.

use %String(MAXLEN="")

Setting MAXLEN="" or MAXLEN=5000 absolutely resolves the issue related to that specific property. But what about other potential huge list of properties within SDA3 structure?

Please read my whole notes.

If you don't define an explicit MAXLEN it is just ignored during validation.
But you may run into problems with ODBC/JDBC   when your VARCHAR or similar just has no maximum SIZE.

So you might instead store your super-long-string into a GlobalStream 
But then you lose all string related operations. It's an option I personally dislike. 

Ok I thought its about just one property. If it's a more generic problem then you should define your own String class extending %Library.String. Here you can not only have the cache params but even your own params related to sda3.

This also can be done for all datatypes if you do need. 

Tirtha the best way to deal with this is to create your own class that extends %String (specify MAXLEN parameter to say 15000) and then change all your persistent classes to override %String with what you just created. Sure this is more work but this is safer and hence is recommended.

Hi Vitaliy,

Thank you for sharing this option; didn't notice the moment when this class emerged. Just found that it exists in Caché 2015.1-2018.1. Not sure how would it work with ODBC/JDBC, but it's up to OP to check this stuff if he needs it.