Fix exception thrown when constructor cannot be found if the constructor is not needed, add some more tests

This commit is contained in:
moparisthebest 2014-06-11 14:30:22 -04:00
parent a3647dd95a
commit 8664d887d2
2 changed files with 41 additions and 9 deletions

View File

@ -67,7 +67,7 @@ public class RowToObjectMapper<T> extends RowMapper {
protected final Object[] _args = new Object[1]; protected final Object[] _args = new Object[1];
public RowToObjectMapper(ResultSet resultSet, Class<T> returnTypeClass) { public RowToObjectMapper(ResultSet resultSet, Class<T> returnTypeClass) {
this(resultSet, returnTypeClass, null, null); this(resultSet, returnTypeClass, null, null);
} }
public RowToObjectMapper(ResultSet resultSet, Class<T> returnTypeClass, Class<?> mapValType) { public RowToObjectMapper(ResultSet resultSet, Class<T> returnTypeClass, Class<?> mapValType) {
@ -99,6 +99,12 @@ public class RowToObjectMapper<T> extends RowMapper {
_fields = null; _fields = null;
try {
_columnCount = resultSet.getMetaData().getColumnCount();
} catch (SQLException e) {
throw new MapperException("RowToObjectMapper: SQLException: " + e.getMessage(), e);
}
// detect if returnTypeClass has a constructor that takes a ResultSet, if so, our job couldn't be easier... // detect if returnTypeClass has a constructor that takes a ResultSet, if so, our job couldn't be easier...
boolean resultSetConstructor = false; boolean resultSetConstructor = false;
Constructor<T> constructor = null; Constructor<T> constructor = null;
@ -114,17 +120,12 @@ public class RowToObjectMapper<T> extends RowMapper {
if (!constructor.isAccessible()) if (!constructor.isAccessible())
constructor.setAccessible(true); constructor.setAccessible(true);
} catch (Throwable e1) { } catch (Throwable e1) {
throw new MapperException("Exception when trying to get constructor for : "+returnTypeClass.getName() + " Must have default no-arg constructor or one that takes a single ResultSet.", e1); if(_columnCount != 1) // if column count is only 1, it might map directly to a type like a Long or something
throw new MapperException("Exception when trying to get constructor for : "+returnTypeClass.getName() + " Must have default no-arg constructor or one that takes a single ResultSet.", e1);
} }
} }
this.resultSetConstructor = resultSetConstructor; this.resultSetConstructor = resultSetConstructor;
this.constructor = constructor; this.constructor = constructor;
try {
_columnCount = resultSet.getMetaData().getColumnCount();
} catch (SQLException e) {
throw new MapperException("RowToObjectMapper: SQLException: " + e.getMessage(), e);
}
} }
/** /**
@ -218,6 +219,8 @@ public class RowToObjectMapper<T> extends RowMapper {
try { try {
resultObject = constructor.newInstance(); resultObject = constructor.newInstance();
} catch (Throwable e) { } catch (Throwable e) {
if(constructor == null) // then this is a different error
throw new MapperException("Exception when trying to get constructor for : "+_returnTypeClass.getName() + " Must have default no-arg constructor or one that takes a single ResultSet.", e);
throw new MapperException(e.getClass().getName() + " when trying to create instance of : " throw new MapperException(e.getClass().getName() + " when trying to create instance of : "
+ _returnTypeClass.getName(), e); + _returnTypeClass.getName(), e);
} }

View File

@ -6,9 +6,10 @@ import org.junit.Assert;
import org.junit.BeforeClass; import org.junit.BeforeClass;
import org.junit.Test; import org.junit.Test;
import java.lang.reflect.Constructor;
import java.sql.Connection; import java.sql.Connection;
import java.sql.DriverManager; import java.sql.DriverManager;
import java.util.Date; import java.util.*;
import static com.moparisthebest.jdbc.TryClose.tryClose; import static com.moparisthebest.jdbc.TryClose.tryClose;
@ -187,6 +188,34 @@ public class QueryMapperTest {
testPerson(reverseSetBoss2, bossUnderscore); testPerson(reverseSetBoss2, bossUnderscore);
} }
@Test
public void testSelectLong() throws Throwable {
Assert.assertEquals(new Long(1L), qm.toObject("SELECT person_no FROM person WHERE person_no = ?", Long.class, 1L));
}
@Test
public void testSelectListMap() throws Throwable {
final List<Map<String, String>> arrayMap = getListMap();
Assert.assertEquals(arrayMap, qm.toListMap("SELECT first_name, last_name FROM person WHERE person_no < 4", arrayMap.get(0).getClass(), String.class));
}
@Test
public void testSelectArrayMap() throws Throwable {
final List<Map<String, String>> arrayMap = getListMap();
Assert.assertEquals(arrayMap.toArray(new Map[arrayMap.size()]), qm.toArrayMap("SELECT first_name, last_name FROM person WHERE person_no < 4", arrayMap.get(0).getClass(), String.class));
}
private List<Map<String, String>> getListMap() {
final List<Map<String, String>> arrayMap = new ArrayList<Map<String, String>>();
for (final Person person : new Person[]{fieldPerson1, fieldBoss1, fieldBoss2}) {
final Map<String, String> map = new HashMap<String, String>();
map.put("last_name", person.getLastName());
map.put("first_name", person.getFirstName());
arrayMap.add(map);
}
return arrayMap;
}
private static void testPerson(final Person expected, final String query) throws Throwable { private static void testPerson(final Person expected, final String query) throws Throwable {
final Person actual = qm.toObject(query, expected.getClass(), expected.getPersonNo()); final Person actual = qm.toObject(query, expected.getClass(), expected.getPersonNo());
//System.out.println("expected: " + expected); //System.out.println("expected: " + expected);