arnaudroger / SimpleFlatMapper

Fast and Easy mapping from database and csv to POJO. A java micro ORM, lightweight alternative to iBatis and Hibernate. Fast Csv Parser and Csv Mapper
http://simpleflatmapper.org
MIT License
439 stars 76 forks source link

Injection point not found #598

Closed pgtaboada closed 5 years ago

pgtaboada commented 5 years ago

Hi,

I have a CSV file with this header:

Patientennummer;Matchcode;Firma;Anrede;Titel;Name;Anschrift;Land;Briefanrede;Behandelt;Telefon1;Telefon2;Telefax;Mobil;Email1;Email2;Geschlecht;Geboren;Datum;Geändert;R_Geboren;Kontoinhaber;Bank;Konto;BLZ;IBAN;BIC;Internet;PatNr;R_Firma1;R_Anrede;R_Titel;R_Name;R_Anschrift;R_Land;R_Briefanrede;Beruf;Familienstand;Größe;Gewicht;Bemerkung;Diagnose;Anamnese;Hinweis;Versicherung;Risikofaktoren;Allergien;Unfälle;Operationen;Dauertherapie;Versicherer;Zahlungsziel;

And I am trying to parse using:

CsvParser .separator(';') .mapTo(SmedPatient.class) .defaultHeaders() .stream(isr) .forEach(p -> { repo.getPatienten().put(p.parsedPatientNummer(), p); });

I have the property annotated as following:

@Column(name="Geändert") private String geaendert;

What am I doing wrong? Is it the umlauts?

arnaudroger commented 5 years ago

The umlauts should not be an issue, it's should all be UTF-8. What's the @Column package? I assume there a setter for geaendert ?

arnaudroger commented 5 years ago

Quick question, why did you use .defaultHeaders(), it probably not do what you think it those, I should deprecate it ... try without it

arnaudroger commented 5 years ago

so the @Column if that the one from javax.persistence wont work without sfm-jdbc - it provides the AliasProvider hooks for it-. There is another way to specify an alias. it's not as straightforward as it should be - will fix that -.

If you use that

CsvParser.separator(';')
    .mapWith(
       CsvMapperFactory
            .newInstance()
            .addAlias("Geändert", "geaendert" )
            .newMapper(SmedPatient.class))
    .stream(isr) .forEach(p -> { repo.getPatienten().put(p.parsedPatientNummer(), p); });

I think it should work

arnaudroger commented 5 years ago

the next release will be easier

CsvParser.separator(';')
    .mapTo(C598.class)
    .alias("Geändert", "geaendert")
    .stream(isr) .forEach(p -> { repo.getPatienten().put(p.parsedPatientNummer(), p); });
pgtaboada commented 5 years ago

Unfortunately, the File is not UTF-8, but I am reading it accordingly:

new InputStreamReader(stream, StandardCharsets.ISO_8859_1)

The Java-Files and therefore the annotation name is indeed UTF-8.

I Removed the "defaultHeaders()" from the configuration, different Problem:

Injection point for on class de.(...).Patient not found

I did not remove the content of "for on class".

arnaudroger commented 5 years ago

have you tried with the mapWith, I created a test for that and with it working?

arnaudroger commented 5 years ago

though injection point is not the error I got. Which version are you running?

pgtaboada commented 5 years ago

I had a very old Version, switched to compile 'org.simpleflatmapper:sfm-csv:6.0.11' but it did not really solve the problem:

org.simpleflatmapper.map.MapperBuildingException: Could not find eligible property for 'Geändert' on class de.(...)SmedPatient not found See https://github.com/arnaudroger/SimpleFlatMapper/wiki/Errors_PROPERTY_NOT_FOUND

I did not try mapWith, I have 52 properties... :)

arnaudroger commented 5 years ago

is the headers part of the file? then you won't need to specify the property, just need to add the alias. or are you saying you have more than one @Column ?

using mapWith does not mean you are providing a static mapper. the CsvMapperFactory will return a dynamic one which will use the first row as headers.

arnaudroger commented 5 years ago

also you try adding sfm-jdbc to the dependency, that should add support for the javax.persistence.Column

pgtaboada commented 5 years ago

The headers are part of the file, I'll try this way

pgtaboada commented 5 years ago

I found a Problem - the header in the file ends with an ";"...

The CsvMapper thinks this is a new "" column and fails.

Unfortunately, the file in question comes from a third party tool and I cannot fix the header.

arnaudroger commented 5 years ago

Hum it should prob handle that. In the mean time there is a work around I’ll get the code You’ll need to

addColumnProperty(« « , ignoreproperty.instance) or similar on the mapper factory

arnaudroger commented 5 years ago

with the CsvMapperFactory

CsvParser.separator(';')
    .mapWith(
       CsvMapperFactory
            .newInstance()
            .addAlias("Geändert", "geaendert" )
        .addColumnProperty("", new IgnoreProperty())  
            .newMapper(SmedPatient.class))
    .stream(isr) .forEach(p -> { repo.getPatienten().put(p.parsedPatientNummer(), p); });

if the @Column works

CsvParser
    .separator(';') 
    .mapTo(SmedPatient.class)
    .columnDefinition("", CsvColumnDefinition.ignoreDefinition())
    .stream(isr) .forEach(p -> { repo.getPatienten().put(p.parsedPatientNummer(), p); });

I'll fix that as well in the next release that should work out of the box

arnaudroger commented 5 years ago

just pushed 6.0.13 to maven central. that should reduce the code needed to just

CsvParser.separator(';')
    .mapTo(C598.class)
    .alias("Geändert", "geaendert")
    .stream(isr) .forEach(p -> { repo.getPatienten().put(p.parsedPatientNummer(), p); });

has it now handles empty trailing headers

pgtaboada commented 5 years ago

Awesome. It worked perfectly after the tips you gave, this is a great lib.

Can you tell how long it takes until it is visible in mvn?

arnaudroger commented 5 years ago

it's there now. thanks for the ticket, those kinds of feedback helps a lot ironing out issues I did not encounter or thought about.