0

I have a fixed-length stream containing record counters

  • Records starts with Z
  • Characters 16+9 (human form) contain B record counter
  • Characters 25+9 (human form) contain C record counter
  • All numbers padded with 0 and aligned to the right
  • Record ends with A + CRLF at position 1898 (record is long 2000 chars)

Following BeanIO mapping code

 <record name="RECORD_Z" class="com.acme.ftt2017.RecordZ" order="4" minOccurs="1" maxOccurs="1" maxLength="1900">
        <field name="tipoRecord" rid="true" at="0" ignore="true" required="true" length="1" lazy="true" literal="Z" />

        <field name="numeroRecordB" at="15" length="9" padding="0" align="right" trim="true" />
        <field name="numeroRecordC" at="24" length="9" padding="0" align="right" trim="true" />

        <field name="terminatorA" at="1897" length="1" rid="true" literal="A" ignore="true" />
    </record>

Bean

public class RecordZ implements Serializable
{    
    private final char tipoRecord = 'Z';

    private Integer numeroRecordB, numeroRecordC;

    // G & S omitted
}

I have triple-checked in debug the following code:

        RecordZ trailer = new RecordZ();
        trailer.setNumeroRecordB(1);
        trailer.setNumeroRecordC(countRecordC); // equals 1 in debug

        log.debug("Exporting record Z");
        log.trace("Record Z: " + trailer.toString());
        exporter.write(FttRecordTypes.RECORDTYPE_FTT_Z, trailer);

However the produced data file contains the following

Z              000000000000000000                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        A

Expected

Z              000000001000000001                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        A

What is wrong with my export code? Why am I getting always zeroes?

usr-local-ΕΨΗΕΛΩΝ
  • 26,101
  • 30
  • 154
  • 305
  • how is `countRecordC` calculated and what is the value of `FttRecordTypes.RECORDTYPE_FTT_Z`? I get the expected output when I set `countRecordC = 1;` – nicoschl Nov 28 '17 at 12:43
  • Also, check that your getters doesn't return the wrong variable or `null` – nicoschl Nov 28 '17 at 12:45
  • Hi, checked that constant equals to `RECORD_Z` and countRecordC **always equals 1**. It is a computed value but I have no case yet in which it is below 1. Debug confirmed 1. Getters & setters double checked. – usr-local-ΕΨΗΕΛΩΝ Nov 28 '17 at 13:12
  • Debugging BeanIO internally I discovered that for a reason unknown to me the type handler for those `Integer`s is `IntFixedLengthTypeHandler` (correct) with property numberOfDigits = 10 (wrong!) – usr-local-ΕΨΗΕΛΩΝ Nov 28 '17 at 13:31
  • I don't have a `IntFixedLengthTypeHandler` in BeanIO 2.1. Which version are you using? You should be able to override the `numberOfDigits` property in your `mapping.xml` – nicoschl Nov 28 '17 at 13:58
  • I am using 2.1.0 too. I have plenties of custom type handlers to handle different-length fields for other record types. This includes an IntFixedLengthTypeHandler of length=10 with a name, which is referenced in other fields where it is needed. I have the suspect that BeanIO wants to use that type handler globally – usr-local-ΕΨΗΕΛΩΝ Nov 28 '17 at 14:03

2 Answers2

0

From the last paragraph in Section 4.3.1

Optionally, a format attribute can be used to pass a decimal format for java.lang.Number types, and for passing a date format for java.util.Date types. In the example below, the hireDate field uses the SimpleDateFormat pattern "yyyy-MM-dd", and the salary field uses the DecimalFormat pattern "#,##0". For more information about supported patterns, please reference the API documentation for Java's java.text.DecimalFormat and java.text.SimpleDateFormat classes.

And in Section 4.3.2

A type handler may be explicitly named using the name attribute, and/or registered for all fields of a particular type by setting the type attribute. The type attribute can be set to the fully qualified class name or type alias of the class supported by the type handler. To reference a named type handler, use the typeHandler field attribute when configuring the field.

Thus, You can try one of 2 things:

Remove the use of your custom *IntegerTypeHandlers and specify a format attribute on the fields which use these custom type handlers. This might be a lot of work depending on the amount of fields and type handlers you have. For example:

<field name="numeroRecordB" format="000000000" at="15" length="9" padding="0" align="right" trim="true" />

OR

Make the getType() method return null instead of Integer.class in your custom type handlers, this will hopefully then not be used as a global type handler. I haven't done this before, so it might not work.

 public Class<?> getType() {
   return null;
 }

Hope this helps.

nicoschl
  • 2,346
  • 1
  • 17
  • 17
0

Discovered the guilty. The custom type handlers!!!!

According to BeanIO

A type handler may be explicitly named using the name attribute, and/or registered for all fields of a particular type by setting the type attribute. The type attribute can be set to the fully qualified class name or type alias of the class supported by the type handler. To reference a named type handler, use the typeHandler field attribute when configuring the field.

So I did not show that in the heading of my file I have registered plenties of custom type handlers, unfortunately all with a type attribute.

<typeHandler name="int_2" type="java.lang.Integer" class="org.beanio.types.IntFixedLengthTypeHandler">
    <property name="numberOfDigits" value="2" />
</typeHandler>
<typeHandler name="int_4" type="java.lang.Integer" class="org.beanio.types.IntFixedLengthTypeHandler">
    <property name="numberOfDigits" value="2" />
</typeHandler>
<typeHandler name="int_10" type="java.lang.Integer" class="org.beanio.types.IntFixedLengthTypeHandler">
    <property name="numberOfDigits" value="10" />
</typeHandler>

<typeHandler name="bigint_16" type="java.math.BigInteger" class="org.beanio.types.BigIntFixedLengthTypeHandler">
    <property name="numberOfDigits" value="16" />
</typeHandler>

Removing the type attribute works

usr-local-ΕΨΗΕΛΩΝ
  • 26,101
  • 30
  • 154
  • 305