SimpleFlatMapper
SimpleFlatMapper copied to clipboard
Map Database Column of Array type to POJO
I am trying to map Postgres array(strings) column to array of strings in POJO - https://www.postgresql.org/docs/9.1/arrays.html to map to POJO
In POJO class
private String[] mystrings;
// getters and setters etc.
For column data like (postgres data below)
{"AA2891"}
By default it maps to something like
"mystrings": [ "{AA2891}" ],
...
instead of
"mystrings": [ "AA2891" ],
...
Referring to this Test case example - https://github.com/arnaudroger/SimpleFlatMapper/blob/7552995ae9a34ebef69a8a336b529b3095252058/sfm-map/src/test/java/org/simpleflatmapper/test/map/FieldMapperColumnDefinitionTest.java
To fix this I am doing something like
// static initializer
SelectQueryMapperFactory.newInstance()
.addColumnProperty(
k -> k.getName().equals("mystrings"), stringArrayGetterFactoryProperty())
.newMapper(MyObject.class);
Following does not work
private GetterFactoryProperty stringArrayGetterFactoryProperty() {
return GetterFactoryProperty.forType(
String.class,
new IndexedGetter<Object, String[]>() {
// It never enters here.
public String[] get(Object rs, int i) {
try {
String[] array = (String[]) ((ResultSet) rs).getArray(i).getArray();
return array;
} catch (SQLException e) {
e.printStackTrace();
}
return null;
}
});
}
Changing above code to forType.(String.class ...
private GetterFactoryProperty stringArrayGetterFactoryProperty() {
return GetterFactoryProperty.forType(
String.class,
new IndexedGetter<Object, String[]>() {
public String[] get(Object rs, int i) {
try {
String[] array = (String[]) ((ResultSet) rs).getArray(i).getArray();
logger.debug("array: ", array);
return array;
} catch (SQLException e) {
e.printStackTrace();
}
return null;
}
});
}
Leads to following exception
java.lang.ArrayStoreException: [Ljava.lang.String;
at org.simpleflatmapper.reflect.setter.IndexedObjectArraySetter.set(IndexedObjectArraySetter.java:14)
at org.simpleflatmapper.reflect.setter.IndexedObjectArraySetter.set(IndexedObjectArraySetter.java:5)
at org.simpleflatmapper.map.fieldmapper.MapperFieldMapper.mapTo(MapperFieldMapper.java:44)
at org.simpleflatmapper.map.generated.none.AsmMapperFromResultSetToStrings_Inj1_I4.mapFields(Unknown Source)
at org.simpleflatmapper.map.generated.none.AsmMapperFromResultSetToStrings_Inj1_I4.mapFields(Unknown Source)
at org.simpleflatmapper.map.mapper.AbstractMapper.map(AbstractMapper.java:23)
at org.simpleflatmapper.map.fieldmapper.MapperFieldMapper.mapTo(MapperFieldMapper.java:40)
at org.simpleflatmapper.map.generated.com.juicymiles.data.v2.entities.AsmMapperFromResultSetToFlightConnectionsInj13_I5.mapFields(Unknown Source)
at org.simpleflatmapper.map.generated.com.juicymiles.data.v2.entities.AsmMapperFromResultSetToFlightConnectionsInj13_I5.mapFields(Unknown Source)
at org.simpleflatmapper.map.mapper.AbstractMapper.map(AbstractMapper.java:23)
at org.simpleflatmapper.map.fieldmapper.MapperFieldMapper.mapTo(MapperFieldMapper.java:40)
at org.simpleflatmapper.map.generated.java.util.AsmMapperFromResultSetToListInj1_I6.mapFields(Unknown Source)
at org.simpleflatmapper.map.generated.java.util.AsmMapperFromResultSetToListInj1_I6.mapFields(Unknown Source)
at org.simpleflatmapper.map.mapper.AbstractMapper.map(AbstractMapper.java:23)
at org.simpleflatmapper.map.fieldmapper.MapperFieldMapper.mapTo(MapperFieldMapper.java:40)
at org.simpleflatmapper.map.generated.com.juicymiles.data.v2.entities.AsmMapperFromResultSetToFlightRoutesInj6_I7.mapFields(Unknown Source)
at org.simpleflatmapper.map.generated.com.juicymiles.data.v2.entities.AsmMapperFromResultSetToFlightRoutesInj6_I7.mapFields(Unknown Source)
at org.simpleflatmapper.map.mapper.AbstractMapper.map(AbstractMapper.java:23)
at org.simpleflatmapper.map.fieldmapper.MapperFieldMapper.mapTo(MapperFieldMapper.java:40)
at org.simpleflatmapper.map.generated.java.util.AsmMapperFromResultSetToListInj1_I8.mapFields(Unknown Source)
at org.simpleflatmapper.map.generated.java.util.AsmMapperFromResultSetToListInj1_I8.mapFields(Unknown Source)
at org.simpleflatmapper.map.mapper.AbstractMapper.map(AbstractMapper.java:23)
at org.simpleflatmapper.map.fieldmapper.MapperFieldMapper.mapTo(MapperFieldMapper.java:40)
at org.simpleflatmapper.map.generated.com.juicymiles.data.v2.entities.AsmMapperFromResultSetToFlightResponsesInj4_I9.mapFields(Unknown Source)
at org.simpleflatmapper.map.generated.com.juicymiles.data.v2.entities.AsmMapperFromResultSetToFlightResponsesInj4_I9.mapFields(Unknown Source)
at org.simpleflatmapper.map.mapper.AbstractMapper.map(AbstractMapper.java:23)
at org.simpleflatmapper.map.mapper.ContextualSourceFieldMapperImpl.map(ContextualSourceFieldMapperImpl.java:38)
at org.simpleflatmapper.map.mapper.JoinMapperEnumerable.next(JoinMapperEnumerable.java:37)
at org.simpleflatmapper.util.EnumerableIterator.fetch(EnumerableIterator.java:26)
at org.simpleflatmapper.util.EnumerableIterator.next(EnumerableIterator.java:33)
at org.simpleflatmapper.jooq.SelectQueryMapper$ExceptionTranslatorIterator.next(SelectQueryMapper.java:300)
at org.simpleflatmapper.util.AutoCloseableIterator.next(AutoCloseableIterator.java:34)
Is there an example that I can refer to?
Will have a look thanks, i think it work directly on a resultset so might be some type thingy not handle properly with jooq
Thanks, while debugging String[] array = (String[]) rs.getArray(i).getArray(); this resolves to correct array value that I need to set to POJO. Please refer to the code snippet above. I think there is some problem with flat mapper when target data type to be set is an array of objects. I am not able to nail it down where exactly its errors out. But seems to me like casting exception.
so I did a quick test
@Test
public void testIssue701StringArray() throws SQLException {
Connection conn = DbHelper.objectDb();
Configuration cfg = new DefaultConfiguration()
.set(conn)
.set(SQLDialect.HSQLDB);
DSLContext dsl = DSL.using(cfg);
SelectSelectStep<Record1<String[]>> select = dsl.select(DSL.val(new String[]{"11", "22"}).as("values"));
SelectQueryMapper<Issue701Pojo> mapper = SelectQueryMapperFactory.newInstance().newMapper(Issue701Pojo.class);
List<Issue701Pojo> pojos = mapper.asList(select);
assertEquals(Arrays.asList(new Issue701Pojo(new String[] {"11", "22"})), pojos);
}
public static class Issue701Pojo {
public final String[] values;
public Issue701Pojo(String[] values) {
this.values = values;
}
@Override
public String toString() {
return "Issue701Pojo{" +
"values=" + Arrays.toString(values) +
'}';
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Issue701Pojo that = (Issue701Pojo) o;
// Probably incorrect - comparing Object[] arrays with Arrays.equals
return Arrays.equals(values, that.values);
}
@Override
public int hashCode() {
return Arrays.hashCode(values);
}
}
and it seems to be working fine. I would prob need more to find out actually what is happening, could you send me the query, the Jooq Model Objects in the query and the Pojos? arnaud.roger at gmail.com
looking at the ArrayStoreException error it tries to set it at and index on the array instead of the array as such. it relates to the way the mapping as resolved prop -> column.
I am not sure if I understand it. Is there any additional info that you need from me that will help?
yes I would need the list of field the select has, and the object it's mapping to
On Thu, Dec 26, 2019 at 6:38 AM Chandan Kumar [email protected] wrote:
I am not sure if I understand it. Is there any additional info that you need from me that will help?
— You are receiving this because you commented. Reply to this email directly, view it on GitHub https://github.com/arnaudroger/SimpleFlatMapper/issues/701?email_source=notifications&email_token=ABPAJLMTWMM6BKGEC2MRJXLQ2RGPLA5CNFSM4J6SBJQKYY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNMVXHJKTDN5WW2ZLOORPWSZGOEHVBA6A#issuecomment-568987768, or unsubscribe https://github.com/notifications/unsubscribe-auth/ABPAJLP5D7DHUSMOSWJYTWTQ2RGPLANCNFSM4J6SBJQA .
I will need sometime to pull out relevant code(I can't post the code as is), I will update you in a couple of days time. Thanks for looking into it.