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

Reply via email to