Product/components used and version/fix level are you on:
Integration Server, 6.5 8.2 to present.
Detailed explanation of the problem:
There are several questions about this topic in the Forum but none has correctly addressed the solution.
If, at the any time in your code you receive a Java Object of a numeric type , which will appear as a box with a “16”, “32”, “64”, “32.” or “64.” label in the pipeline editor, you should use the public function pub.string:objectToString in a transformer to convert it.
As already explained elsewhere, if you output comes from an adapter, and you can modify it, you should set the output type of a field to “String”, leaving the adapter to make the conversion for you.
WmTransformationServices package also has a pile of services for various type conversions.
For Java services an easy trick is to just use concat to convert numeric types to string.
int a = 123;
String s = a+“”;
Another thing to keep in mind – avoid the use of float and double (and Float/Double wrappers) if accuracy is important. For most business integrations, it is important to get monetary values correct. There are various articles on the web describing the issues. And many discussions about speed and precision and such. Many folks refer to using rounding and truncating to address the issues with binary floating point arithmetic–but accumulated errors over several calculations can be a problem.
This means the *Floats services in pub.math are to be avoided. Using them has a high likelihood of being an issue at some point – and is usually one of the silent issues that no one can seem to figure out why reconciliation is off. For example:
Of course rounding would address this, by why should we need to round in this case? Just avoid using float/double to avoid the issue.
Another item to be aware of is how Integration Server handles JSON. By default, it uses native types. As we know, JSON is a string representation. So IS converts strings to native types and vice versa. This alone, depending upon the specific values and the JVM (to some degree) can introduce accuracy errors. Beware.
It is relatively easy to create your own services for arithmetic using BigDecimal within. It has its own set of pitfalls so be aware of those.
If anyone is curious about this, run pub.math:multiplyFloats with 3 and 13.2 as input. You’ll be surprised with the result.
We do the same. For JSON activity, such as jsonToDocument, we always immediately convert the “native” types to strings.
We use WmTransformationServices sparingly. PSUtilities is forbidden from being anywhere but in a dev environment. When there is something useful there, we copy it to our own *Public package and edit as needed/desired.
True that FLOW doesn’t give you feedback about “incompatible types” that way a compiler will. Developer’s need to pay attention. And understand there is a difference between an element type declared at design-time and an element as it exists at run-time. They need to be the same but if one misconfigures or misses something, the run-time type might be different that expected.
True, but it appears there are still scenarios where the result is not as expected. And where float/double is still used.
Omit the precision input and this is the result.
Specify a precision and you get what you expect:
Specify a precision of 14 or higher (for this operation) and things go astray again. I’m not sure if this because BigDecimal is doing this or if the underlying code is reverting to using double operations.
The config setting for watt.server.math.floatOperation.mode is also a factor.
I guess I would revise my comment about the pub.math:*Float services from “to be avoided” to “be aware of how they function.” Which one would need to do as well if one created your own services based upon BigDecimal.
great debate, my opinion is also in line with @reamon, generally don’t use strong types in an integration service. No real advantage and lots of conversion nightmares.
That’s why in 10.15 we went back to our json services, which were out of kilter with this pattern and decided to create a new replacement service, namely;
This service assumes that everything should be treated as strings, unless otherwise stated or defined by a Document type if provided. We decided to create a new service to avoid introducing breaking changes into existing use. So the above service should be your go to service for json transformation.
However, this is not a hard rule as their are also exceptions such a using Date objects with JDBC adapter services, and you certainly should not try this with the implementation of a java service. The signature can be string only, but you should then convert to proper java types in the body of the code.
This is where I’ve been hoping for help from documentToJSONString – let the caller indicate/tell which fields to treat as objects and not enquote them. Should not need to convert these from strings to objects (boolean and numbers) just to avoid the " " in the JSON representation.