diff --git a/jdbcmapper/src/main/java/com/moparisthebest/jdbc/codegen/CompileTimeRowToObjectMapper.java b/jdbcmapper/src/main/java/com/moparisthebest/jdbc/codegen/CompileTimeRowToObjectMapper.java index 31a8add..ffcb2e8 100644 --- a/jdbcmapper/src/main/java/com/moparisthebest/jdbc/codegen/CompileTimeRowToObjectMapper.java +++ b/jdbcmapper/src/main/java/com/moparisthebest/jdbc/codegen/CompileTimeRowToObjectMapper.java @@ -188,7 +188,7 @@ public class CompileTimeRowToObjectMapper { continue; final ExecutableElement m = (ExecutableElement) e; //System.out.printf("method: '%s', isSetterMethod: '%s'\n", m, isSetterMethod(m)); - if (isSetterMethod(m)) { + if (isSetterMethod(m, declaredReturnType)) { // todo: in RowToObjectMapper we send in this top one, but how does it or this handle methods on parent classes? String fieldName = m.getSimpleName().toString().substring(3).toUpperCase(); //System.out.println("METHOD-fieldName1: "+fieldName); if (!mapFields.containsKey(fieldName)) { @@ -289,13 +289,14 @@ public class CompileTimeRowToObjectMapper { * @param method Method to check * @return True if the method is a setter method. */ - protected boolean isSetterMethod(final ExecutableElement method) { + protected boolean isSetterMethod(final ExecutableElement method, final TypeMirror enclosingClass) { if (method.getSimpleName().toString().startsWith("set")) { final Set modifiers = method.getModifiers(); if (modifiers.contains(Modifier.STATIC)) return false; if (!modifiers.contains(Modifier.PUBLIC)) return false; - if (TypeKind.VOID != method.getReturnType().getKind()) return false; + final TypeMirror methodReturnType = method.getReturnType(); + if (TypeKind.VOID != method.getReturnType().getKind() && !rsm.types.isSameType(enclosingClass, methodReturnType)) return false; // method parameter checks final List params = method.getParameters(); diff --git a/jdbcmapper/src/test/java/com/moparisthebest/jdbc/codegen/JdbcMapperTest.java b/jdbcmapper/src/test/java/com/moparisthebest/jdbc/codegen/JdbcMapperTest.java index 6da4449..ffb9594 100644 --- a/jdbcmapper/src/test/java/com/moparisthebest/jdbc/codegen/JdbcMapperTest.java +++ b/jdbcmapper/src/test/java/com/moparisthebest/jdbc/codegen/JdbcMapperTest.java @@ -216,6 +216,11 @@ public class JdbcMapperTest { assertEquals(fieldPerson1, dao.getPerson(fieldPerson1.getPersonNo())); } + @Test + public void testBuilderPerson() throws SQLException { + assertEquals(new BuilderPerson(fieldPerson1), dao.getBuilderPerson(fieldPerson1.getPersonNo())); + } + @Test public void testSinglePersonNameArray() throws SQLException { assertArrayEquals(new String[]{fieldPerson1.getFirstName(), fieldPerson1.getLastName()}, dao.getSinglePersonNameArray(fieldPerson1.getPersonNo())); diff --git a/jdbcmapper/src/test/java/com/moparisthebest/jdbc/codegen/PersonDAO.java b/jdbcmapper/src/test/java/com/moparisthebest/jdbc/codegen/PersonDAO.java index 91d4833..a5e9eda 100644 --- a/jdbcmapper/src/test/java/com/moparisthebest/jdbc/codegen/PersonDAO.java +++ b/jdbcmapper/src/test/java/com/moparisthebest/jdbc/codegen/PersonDAO.java @@ -75,6 +75,9 @@ public interface PersonDAO extends JdbcMapper { @JdbcMapper.SQL(value = "SELECT person_no, first_name, last_name, birth_date FROM person WHERE person_no = {personNo}") FieldPerson getPerson(long personNo) throws SQLException; + @JdbcMapper.SQL(value = "SELECT person_no, first_name, last_name, birth_date FROM person WHERE person_no = {personNo}") + BuilderPerson getBuilderPerson(long personNo) throws SQLException; + @JdbcMapper.SQL("SELECT first_name, last_name, birth_date FROM person WHERE person_no = {personNo}") FieldPerson getPerson(long personNo, Calendar cal) throws SQLException; diff --git a/querymapper/src/main/java/com/moparisthebest/jdbc/RowToObjectMapper.java b/querymapper/src/main/java/com/moparisthebest/jdbc/RowToObjectMapper.java index fdd0b89..7cc672d 100644 --- a/querymapper/src/main/java/com/moparisthebest/jdbc/RowToObjectMapper.java +++ b/querymapper/src/main/java/com/moparisthebest/jdbc/RowToObjectMapper.java @@ -430,7 +430,7 @@ public class RowToObjectMapper extends AbstractRowMapper { Method[] classMethods = _returnTypeClass.getMethods(); for (Method m : classMethods) { //System.out.printf("method: '%s', isSetterMethod: '%s'\n", m, isSetterMethod(m)); - if (isSetterMethod(m)) { + if (isSetterMethod(m, _returnTypeClass)) { String fieldName = m.getName().substring(3).toUpperCase(); //System.out.println("METHOD-fieldName1: "+fieldName); if (!mapFields.containsKey(fieldName)) { @@ -551,12 +551,13 @@ public class RowToObjectMapper extends AbstractRowMapper { * @param method Method to check * @return True if the method is a setter method. */ - protected boolean isSetterMethod(Method method) { + protected boolean isSetterMethod(final Method method, final Class enclosingClass) { if (method.getName().startsWith("set")) { if (Modifier.isStatic(method.getModifiers())) return false; if (!Modifier.isPublic(method.getModifiers())) return false; - if (!Void.TYPE.equals(method.getReturnType())) return false; + final Class methodReturnType = method.getReturnType(); + if (!Void.TYPE.equals(methodReturnType) && !enclosingClass.equals(methodReturnType)) return false; // method parameter checks Class[] params = method.getParameterTypes(); diff --git a/querymapper/src/test/java/com/moparisthebest/jdbc/QueryMapperTest.java b/querymapper/src/test/java/com/moparisthebest/jdbc/QueryMapperTest.java index 697eddd..313a55f 100644 --- a/querymapper/src/test/java/com/moparisthebest/jdbc/QueryMapperTest.java +++ b/querymapper/src/test/java/com/moparisthebest/jdbc/QueryMapperTest.java @@ -164,6 +164,11 @@ public class QueryMapperTest { testPerson(fieldPerson1, personRegular); } + @Test + public void testBuilderPerson() throws Throwable { + testPerson(new BuilderPerson(fieldPerson1), personRegular); + } + @Test public void testFieldRegularAndUnderscore() throws Throwable { testPerson(fieldBoss1, bossRegularAndUnderscore); diff --git a/querymapper/src/test/java/com/moparisthebest/jdbc/dto/BuilderPerson.java b/querymapper/src/test/java/com/moparisthebest/jdbc/dto/BuilderPerson.java new file mode 100644 index 0000000..29ee4ca --- /dev/null +++ b/querymapper/src/test/java/com/moparisthebest/jdbc/dto/BuilderPerson.java @@ -0,0 +1,82 @@ +package com.moparisthebest.jdbc.dto; + +import java.util.Date; + +public class BuilderPerson implements Person { + + protected long personNo; + protected Date birthDate; + protected String firstName; + protected String lastName; + + private boolean setterCalled = false; + + public BuilderPerson() { + } + + public BuilderPerson(Person person) { + this.personNo = person.getPersonNo(); + this.birthDate = person.getBirthDate(); + this.lastName = person.getLastName(); + this.firstName = person.getFirstName(); + this.setterCalled = true; // for convenience + } + + @Override + public long getPersonNo() { + return personNo; + } + + public BuilderPerson setPersonNo(final long personNo) { + this.personNo = personNo; + this.setterCalled = true; + return this; + } + + @Override + public Date getBirthDate() { + return birthDate; + } + + public BuilderPerson setBirthDate(final Date birthDate) { + this.birthDate = birthDate; + this.setterCalled = true; + return this; + } + + @Override + public String getFirstName() { + return firstName; + } + + public BuilderPerson setFirstName(final String firstName) { + this.firstName = firstName; + this.setterCalled = true; + return this; + } + + @Override + public String getLastName() { + return lastName; + } + + public BuilderPerson setLastName(final String lastName) { + this.lastName = lastName; + this.setterCalled = true; + return this; + } + + @Override + public boolean equals(final Object o) { + if(!setterCalled || (o instanceof BuilderPerson && !((BuilderPerson)o).setterCalled)) + throw new RuntimeException("setter not called"); + return PersonEqualsHashCode.equals(this, o); + } + + @Override + public int hashCode() { + if(!setterCalled) + throw new RuntimeException("setter not called"); + return PersonEqualsHashCode.hashCode(this); + } +} diff --git a/querymapper/src/test/java/com/moparisthebest/jdbc/dto/FieldPerson.java b/querymapper/src/test/java/com/moparisthebest/jdbc/dto/FieldPerson.java index 1299b5c..9b12b1a 100644 --- a/querymapper/src/test/java/com/moparisthebest/jdbc/dto/FieldPerson.java +++ b/querymapper/src/test/java/com/moparisthebest/jdbc/dto/FieldPerson.java @@ -46,27 +46,13 @@ public class FieldPerson implements Person { } @Override - public boolean equals(Object o) { - if (this == o) return true; - if (!(o instanceof FieldPerson)) return false; - - FieldPerson person = (FieldPerson) o; - - if (personNo != person.personNo) return false; - if (birthDate != null ? !birthDate.equals(person.birthDate) : person.birthDate != null) return false; - if (firstName != null ? !firstName.equals(person.firstName) : person.firstName != null) return false; - if (lastName != null ? !lastName.equals(person.lastName) : person.lastName != null) return false; - - return true; + public boolean equals(final Object o) { + return PersonEqualsHashCode.equals(this, o); } @Override public int hashCode() { - int result = (int) (personNo ^ (personNo >>> 32)); - result = 31 * result + (birthDate != null ? birthDate.hashCode() : 0); - result = 31 * result + (firstName != null ? firstName.hashCode() : 0); - result = 31 * result + (lastName != null ? lastName.hashCode() : 0); - return result; + return PersonEqualsHashCode.hashCode(this); } @Override diff --git a/querymapper/src/test/java/com/moparisthebest/jdbc/dto/PersonEqualsHashCode.java b/querymapper/src/test/java/com/moparisthebest/jdbc/dto/PersonEqualsHashCode.java new file mode 100644 index 0000000..160d917 --- /dev/null +++ b/querymapper/src/test/java/com/moparisthebest/jdbc/dto/PersonEqualsHashCode.java @@ -0,0 +1,25 @@ +package com.moparisthebest.jdbc.dto; + +public class PersonEqualsHashCode { + public static boolean equals(final Person thiss, final Object o) { + if (thiss == o) return true; + if (!(o instanceof Person)) return false; + + final Person that = (Person) o; + + if (thiss.getPersonNo() != that.getPersonNo()) return false; + if (thiss.getBirthDate() != null ? !thiss.getBirthDate().equals(that.getBirthDate()) : that.getBirthDate() != null) + return false; + if (thiss.getFirstName() != null ? !thiss.getFirstName().equals(that.getFirstName()) : that.getFirstName() != null) + return false; + return thiss.getLastName() != null ? thiss.getLastName().equals(that.getLastName()) : that.getLastName() == null; + } + + public static int hashCode(final Person thiss) { + int result = (int) (thiss.getPersonNo() ^ (thiss.getPersonNo() >>> 32)); + result = 31 * result + (thiss.getBirthDate() != null ? thiss.getBirthDate().hashCode() : 0); + result = 31 * result + (thiss.getFirstName() != null ? thiss.getFirstName().hashCode() : 0); + result = 31 * result + (thiss.getLastName() != null ? thiss.getLastName().hashCode() : 0); + return result; + } +}