Reputation: 155
I am working on dynamically mapping values from ResultSet to POJO in java. I am able to get the values but don't know how to set those value to the pojo. Any suggestions? Thanks in Advance !!
List<T> results = new ArrayList<>();
while(resultSet.next())
{
T newObj = clazz.newInstance();
for (Field field : clazz.getDeclaredFields())
{
String fieldName = field.getName().toLowerCase();
if (columnNames.containsKey(fieldName))
{
final int index = columnNames.get(fieldName);
field.set(fieldName, resultSet.getObject(index+1));
}
}
results.add(newObj);
}
Upvotes: 0
Views: 2003
Reputation: 298529
The first argument to Field.set
must be the object, if it is an instance field, or null
for static
field. You are passing fieldName
instead, which is obviously wrong.
So change
field.set(fieldName, resultSet.getObject(index+1));
to
field.set(newObj, resultSet.getObject(index+1));
When your code doesn’t have the necessary access rights, it may need to set the “accessible” state on the Field
object. But generally, you should avoid repeating such expensive operations for every row of the ResultSet
. So, you may use
List<T> results = new ArrayList<>();
Field[] theFields = clazz.getDeclaredFields();
// if overriding access right is needed:
AccessibleObject.setAccessible(theFields, true);
while(resultSet.next())
{
T newObj = clazz.newInstance();
for (Field field: theFields)
{
Integer index = columnNames.get(field.getName().toLowerCase());
if(index != null)
field.set(newObj, resultSet.getObject(index+1));
}
results.add(newObj);
}
instead. Or even
List<T> results = new ArrayList<>();
Field[] theFields = clazz.getDeclaredFields();
// if overriding access right is needed:
AccessibleObject.setAccessible(theFields, true);
int numberOfFields = theFields.length;
int[] columnIndex = new int[numberOfFields];
for(int ix = 0; ix < numberOfFields; ix++) {
Integer index = columnNames.get(theFields[ix].getName().toLowerCase());
if(index != null) columnIndex[ix] = index + 1;
}
Constructor<T> con = clazz.getConstructor();
while(resultSet.next())
{
T newObj = con.newInstance();
for(int ix = 0; ix < numberOfFields; ix++)
if(columnIndex[ix] != 0)
theFields[ix].set(newObj, resultSet.getObject(columnIndex[ix]));
results.add(newObj);
}
which is more complicated in the initialization, but reducing the repeated work inside the loop even further. Note that using Constructor
here is more than an optimization, as starting with Java 9, Class.newInstance()
has been marked deprecated.
Upvotes: 1
Reputation: 2376
Get familiar with FieldUtils package from apache commons, exactly with writeDeclaredField method:
@Test
public void testWriteDeclaredNamedField() {
FieldUtils.writeDeclaredField(object, "fieldName", "fieldValue");
assertEquals("fieldValue", FieldUtils.readDeclaredField(object, "fieldName"));
}
Upvotes: 0
Reputation: 798
Can you try below line before setting value?
field.setAccessible(true);
Upvotes: 0