I have recently migrated from 4.0 to 4.1. I have a few instances where I
perform a query and then I create an instance of my entity from the resulting
DataRow. These object entities have both Integer and Boolean fields. DataRow
has always cast these fields as BigDecimal.
In 4.0 the DataContext.objectFromDataRow handled these fields, evidently
because CayenneDataObject could put BigDecimal into the values map of <String,
Object>.
In 4.1 it appears as though each entity implements its own
writePropertyDirectly which puts the object into a typed field of that entity.
The objectFromDataRow fails because of the cast exception from BigDecimal to
Boolean or BigDecimal to Integer. So these fields evidently need to be
converted to correct types before being set on the entity.
My workaround is to write a utility method that cleans up the DataRow before I
hand it to objectFromDataRow. The utility method looks for any attributes that
are BigDecimal on the DataRow, then for the same field name in the entity, it
looks for the desired type. Then it does an appropriate conversion from
BigDecimal.
public static void cleanUpDataRow(DataContext dContext, Class clazz,
DataRow dataRow) {
ObjEntity entity =
dContext.getEntityResolver().getObjEntity(clazz);
Collection<ObjAttribute> entityAttributes =
entity.getAttributes();
for(ObjAttribute attribute : entityAttributes) {
String attributeClass = attribute.getType();
if(dataRow.get(attribute.getDbAttributeName()) != null &&
dataRow.get(attribute.getDbAttributeName()).getClass().getTypeName().equals("java.math.BigDecimal"))
{
if(attributeClass.equals("java.lang.Boolean")) {
dataRow.put(attribute.getDbAttributeName(),
(dataRow.get(attribute.getDbAttributeName()).equals(BigDecimal.valueOf(1))));
} else
if(attributeClass.equals("java.lang.Integer")) {
dataRow.put(attribute.getDbAttributeName(),
((BigDecimal)dataRow.get(attribute.getDbAttributeName())).intValue());
}
}
}
}
Usage:
...
CayennePatch.cleanUpDataRow(dContext, ROrganizationalChart.class, dataRow);
ROrganizationalChart fetchedChart =
dataContext.objectFromDataRow(ROrganizationalChart.class, dataRow);
...
How can I use DataRows in 4.1 with objectFromDataRow without using a custom
method?
Thank you!
Andrew