Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Set of custom objects with IGNORE_UNKNOWN brokes silently csv #51

Closed
pimuzzo opened this issue Nov 4, 2017 · 3 comments
Closed

Set of custom objects with IGNORE_UNKNOWN brokes silently csv #51

pimuzzo opened this issue Nov 4, 2017 · 3 comments
Labels
Milestone

Comments

@pimuzzo
Copy link

pimuzzo commented Nov 4, 2017

When I use a Set (but I think a Collection) of objects with feature JsonGenerator.Feature.IGNORE_UNKNOWN extra line separators are added.
I paste the code to reproduce it:

    protected static class Person
    {
        private String name;
        private String surname;

        public Person()
        {
        }

        public Person( String name, String surname )
        {
            this.name = name;
            this.surname = surname;
        }

        public String getName()
        {
            return name;
        }

        public void setName( String name )
        {
            this.name = name;
        }

        public String getSurname()
        {
            return surname;
        }

        public void setSurname( String surname )
        {
            this.surname = surname;
        }
    }

    protected static class MyClass
    {
        private Set<Person> people;
        private String address;
        private String phoneNumber;

        public MyClass()
        {
        }

        public Set<Person> getPeople()
        {
            return people;
        }

        public void setPeople( Set<Person> people )
        {
            this.people = people;
        }

        public String getAddress()
        {
            return address;
        }

        public void setAddress( String address )
        {
            this.address = address;
        }

        public String getPhoneNumber()
        {
            return phoneNumber;
        }

        public void setPhoneNumber( String phoneNumber )
        {
            this.phoneNumber = phoneNumber;
        }
    }

    public void testEmbeddedObjects() throws Exception
    {
        CsvMapper mapper = mapperForCsv();
        mapper.configure( JsonGenerator.Feature.IGNORE_UNKNOWN, true );
        CsvSchema schema = CsvSchema.builder()
                .addColumn( "people" ) // here I'm skipping phoneNumber so I need to use IGNORE_UNKNOWN feature
                .addColumn( "address" )
                .build()
                .withHeader();

        Person firstPerson = new Person( "Barbie", "Benton" );
        Person secondPerson = new Person( "Veltto", "Virtanen" );
        Set<Person> people = new HashSet<>();
        people.add( firstPerson );
        people.add( secondPerson );
        MyClass myClass = new MyClass();
        myClass.setPeople( people );
        myClass.setAddress( "AAA" );
        myClass.setPhoneNumber( "123" );

        String result = mapper.writer( schema ).writeValueAsString( myClass );
        int numberOfLines = result.split( "\n" ).length;
        assertEquals( 2, numberOfLines ); // header and data (here fails with 3)
    }

Version is 2.9.0
A workaround would be to write a custom serializer, but with a class with a lot of fields it was very hard to find which field has broken silently the csv.
Is there any way to use the toString rappresentation for cases like this one?
If you prefer I can open a PR with that code instead of paste it here.

@pimuzzo pimuzzo changed the title (csv) Set of custom objects with IGNORE_UNKNOWN broke silently csv (csv) Set of custom objects with IGNORE_UNKNOWN brokes silently csv Nov 4, 2017
@cowtowncoder
Copy link
Member

Thank you for reporting this. Broken output is wrong, regardless, so I hope this is something that can just be fixed. I am not against option(s) that allow choosing simple toString() to be used, if a good API approach can be found (that is, simple, consistent with existing config options, intuitive).

cowtowncoder added a commit that referenced this issue Nov 7, 2017
@cowtowncoder
Copy link
Member

Ok. So the technical challenge is that END_OBJECT for nested object is assumed to be the end of outermost object, which should trigger end-of-line. In this case this is false assumption, due to nesting.
I will have to think about how to handle this more reliably, first, to get rid of the false linefeed.

Second problem, then, is whether there might be better handling here for nested POJOs: as things are, arrays can be handled by using array separator. But it is not clear what should be done for contents.
I think use of @JsonValue for Person might work here, I'll check that to make sure.

@cowtowncoder
Copy link
Member

Yes; use of @JsonValue does work, for serialization, and in this particular case actually even prevents the linefeed (because no START_OBJECT/END_OBJECT writes are done, given that value becomes just a String).

@pimuzzo You may see if @JsonValue on Person might work for you. I will try to resolve the output problem wrt linefeed.

@cowtowncoder cowtowncoder added this to the 2.9.3 milestone Nov 7, 2017
@cowtowncoder cowtowncoder changed the title (csv) Set of custom objects with IGNORE_UNKNOWN brokes silently csv Set of custom objects with IGNORE_UNKNOWN brokes silently csv Nov 7, 2017
cowtowncoder added a commit that referenced this issue May 4, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants