Search code examples
javaannotationsmarshallingbean-io

BeanIO - Collection of abstract class or class implementing interface


Is it possible, using the BeanIO annotations, to define a field as a collection of an abstract class, or a collection of classes implementing an interface?

What I want is this:

@Record(minOccurs = 1, maxOccurs = -1, collection = List.class)
List<SomeInterface> records;

I then supply a list of different concrete classes to the collection, which all contains all the annotations for defining a valid record.

However I just get an error saying

Repeating segments without any child field component must have minOccurs=maxOccurs

...which kind of defeats the purpose.

Some things I have tried:

  • Setting the stream to writeOnly
  • Using an abstract class instead of an interface

EDIT: This is my configuration:

  StreamFactory factory = StreamFactory.newInstance();
  StreamBuilder builder = new StreamBuilder("MyStreamName")
                .writeOnly()
                .format("delimited")
                .parser(new DelimitedParserBuilder(','))
                .addGroup(Parent.class);
  factory.define(builder);

...whereas the Parent.class contains the List<SomeInterface> records;

Logically, there should be something tying the SomeInterface to the concrete implementations of the interface so that BeanIO could figure out what to do, but I can't seem to figure out how to set up this connection.


Solution

  • The following is working for me:

    import org.beanio.annotation.Record;
    
    @Record(name = "parentRecord", maxOccurs = 1, minOccurs = 1, collection = List.class)
    public class Parent {
    
      @Record(minOccurs = 1, collection = List.class, name = "recordList")
      private List<A> records;
    
      // getter + setter
    }
    

    The Parent class is now a @Record which need a change in the StreamBuilder to

    final StreamFactory factory = StreamFactory.newInstance();
    final StreamBuilder builder = new StreamBuilder("MyStreamName")
      .writeOnly()
      .format("delimited")
      .parser(new DelimitedParserBuilder(','))
      .addRecord(Parent.class);
    factory.define(builder);
    

    This runs for me without any exceptions