From 8664d887d21bb733ce7c1f017dab1d6c0d5624bd Mon Sep 17 00:00:00 2001 From: moparisthebest Date: Wed, 11 Jun 2014 14:30:22 -0400 Subject: [PATCH] Fix exception thrown when constructor cannot be found if the constructor is not needed, add some more tests --- .../jdbc/RowToObjectMapper.java | 19 +++++++----- .../moparisthebest/jdbc/QueryMapperTest.java | 31 ++++++++++++++++++- 2 files changed, 41 insertions(+), 9 deletions(-) diff --git a/beehive-jdbc-mapper/src/main/java/com/moparisthebest/jdbc/RowToObjectMapper.java b/beehive-jdbc-mapper/src/main/java/com/moparisthebest/jdbc/RowToObjectMapper.java index e48d70b..744a34b 100644 --- a/beehive-jdbc-mapper/src/main/java/com/moparisthebest/jdbc/RowToObjectMapper.java +++ b/beehive-jdbc-mapper/src/main/java/com/moparisthebest/jdbc/RowToObjectMapper.java @@ -67,7 +67,7 @@ public class RowToObjectMapper extends RowMapper { protected final Object[] _args = new Object[1]; public RowToObjectMapper(ResultSet resultSet, Class returnTypeClass) { - this(resultSet, returnTypeClass, null, null); + this(resultSet, returnTypeClass, null, null); } public RowToObjectMapper(ResultSet resultSet, Class returnTypeClass, Class mapValType) { @@ -99,6 +99,12 @@ public class RowToObjectMapper extends RowMapper { _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... boolean resultSetConstructor = false; Constructor constructor = null; @@ -114,17 +120,12 @@ public class RowToObjectMapper extends RowMapper { if (!constructor.isAccessible()) constructor.setAccessible(true); } 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.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 extends RowMapper { try { resultObject = constructor.newInstance(); } 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 : " + _returnTypeClass.getName(), e); } diff --git a/beehive-jdbc-mapper/src/test/java/com/moparisthebest/jdbc/QueryMapperTest.java b/beehive-jdbc-mapper/src/test/java/com/moparisthebest/jdbc/QueryMapperTest.java index c4ae8fb..49b9fb8 100644 --- a/beehive-jdbc-mapper/src/test/java/com/moparisthebest/jdbc/QueryMapperTest.java +++ b/beehive-jdbc-mapper/src/test/java/com/moparisthebest/jdbc/QueryMapperTest.java @@ -6,9 +6,10 @@ import org.junit.Assert; import org.junit.BeforeClass; import org.junit.Test; +import java.lang.reflect.Constructor; import java.sql.Connection; import java.sql.DriverManager; -import java.util.Date; +import java.util.*; import static com.moparisthebest.jdbc.TryClose.tryClose; @@ -187,6 +188,34 @@ public class QueryMapperTest { 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> 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> 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> getListMap() { + final List> arrayMap = new ArrayList>(); + for (final Person person : new Person[]{fieldPerson1, fieldBoss1, fieldBoss2}) { + final Map map = new HashMap(); + 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 { final Person actual = qm.toObject(query, expected.getClass(), expected.getPersonNo()); //System.out.println("expected: " + expected);