0

I have a requirement where I need to write a field value onto file with max length as 25. From DB I am getting length as 30. I am using 'maxLength=25' attribute in beanio mapping file.It somehow is still allowing value with length greater than 25. Anyone can suggest any solution or workaround for same?

  • Are you writing to a delimited format or fixed length format? Can you give us some example code demonstrating the problem, especially your `mapping.xml` file or the classes with annotations? – nicoschl Jul 17 '18 at 12:26
  • I have modified a small project to be fixed length format and it is working as expected. Show us what you have done and then we can help you – nicoschl Jul 17 '18 at 20:25
  • Below is the mapping.xml. For firstName i want that length should not exceed 25. yes I am writing to delimited format – Bhupinder Verma Jul 18 '18 at 07:56

1 Answers1

0

It is not possible to force BeanIO validations when writing (marshalling) objects to an OutputStream for delimited formats from my understanding of the documentation, according to Section 4.6.2 Field Validation. Emphasis mine.

4.6.2. Field Validation

BeanIO supports several common field validation rules when reading an input stream. All field validation rules are validated against the field text before type conversion. When field trimming is enabled, trim="true", all validations are performed after the field's text has first been trimmed. Field validations are ignored when writing to an output stream.

I guess it is working for fixed length formats otherwise you would have an invalid record (although the same argument probably applies to any format)

You have 2 options here:

  1. Enforce the maximum length in your setter and/or getter methods if you want to be paranoid. This will affect your entire application (although I think it is a good idea to ensure your data consistency). You could do this in various ways and with the help of libraries (Apache Commons Lang's StringUtils come to mind). I'm leaving out any null checks, which you should take care of when using these approaches.

    public String getFirstName() {
       return firstName.substring(0, 25); // this should really not be necessary if you use the setter
    }
    
    public void setFirstName(final String newFirstName) {
      firstName = newFirstName.substring(0, 25);
    }
    

    This would not require any changes in your mapping.xml file.

  2. Enforce the maximum length in an alternative setter and/or getter methods used explicitly by BeanIO for writing (marshalling) your data. Your getter/setter methods then don't do anything special and you add a new getter/setter pair per field. You could use just a custom getter method when you only want to enforce the length when writing the data.

    public String getFirstName() {
       return firstName; 
    }
    
    public void setFirstName(final String newFirstName) {
      firstName = newFirstName;
    }
    
    // the BeanIO specific getter/setter
    public String getFirstNameBIO() {
      return firstName.substring(0, 25);
    }
    
    public void setFirstNameBIO(final String newFirstName) {
      firstName = newFirstName.substring(0, 25);
    }
    

    This would also require changes in your mapping.xml file.

    <?xml version="1.0" encoding="UTF-8"?>
    <beanio xmlns="http://www.beanio.org/2012/03"
            xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
            xsi:schemaLocation="http://www.beanio.org/2012/03 http://www.beanio.org/2012/03/mapping.xsd">
    
      <stream name="DailyCasesSndStream" format="delimited" strict="true">
        <parser>
          <property name="delimiter" value="|"/>
        </parser>
        <record name="DailyCasesRecord" class="com.run.daily.batch.util.DailyCasesRecord" minOccurs="0"
                maxOccurs="unbounded">
          <field name="firstName" maxLength="25" getter="getFirstNameBIO" setter="setFirstNameBIO"/>
          <!-- OR if you only want the new getter to be used -->
          <field name="midName" maxLength="25" getter="getMidNameBIO"/>
        </record>
      </stream>
    </beanio>
    

    Using this test code:

    final DailyCasesRecord dailyCasesRecord = new DailyCasesRecord();
    dailyCasesRecord.setFirstName("FirstNameFirstNameFirstName");
    dailyCasesRecord.setMidNameBIO("MidNameMidNameMidNameMidName");
    
    final StreamFactory factory = StreamFactory.newInstance();
    factory.loadResource("mapping.xml");
    BeanWriter beanWriter = null;
    try (final StringWriter out = new StringWriter()) {
      beanWriter = factory.createWriter("DailyCasesSndStream", out);
      beanWriter.write(dailyCasesRecord);
      System.out.println(out.toString());
    } catch (final Exception e) {
      System.err.println(e.getMessage());
    } finally {
      if (beanWriter != null) {
        beanWriter.close();
      }
    }
    

    I get this output:

    FirstNameFirstNameFirstNa|MidNameMidNameMidNameMidN
    
nicoschl
  • 2,346
  • 1
  • 17
  • 17