Skip to content

Commit

Permalink
Merge pull request #32 from sykesd/31-delegated-properties-can-cause-NPE
Browse files Browse the repository at this point in the history
Reproduction test case and fix
  • Loading branch information
sykesd authored Apr 19, 2018
2 parents 4d0fa9a + 576624d commit aad8b64
Show file tree
Hide file tree
Showing 3 changed files with 88 additions and 3 deletions.
14 changes: 11 additions & 3 deletions src/org/dt/japper/MapperCodeGenerator.java
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
import java.sql.SQLException;
import java.sql.Timestamp;
import java.sql.Types;
import java.util.Arrays;
import java.util.Comparator;
import java.util.Map;
import java.util.TreeMap;
Expand Down Expand Up @@ -161,7 +162,7 @@ private static <T> String buildMapMethodBody(Class<T> resultType, ResultSetMetaD

for (int i = 1; i <= metaData.getColumnCount(); i++) {
PropertyDescriptor[] path = matcher.match(metaData.getColumnLabel(i), metaData.getTableName(i), metaData.getColumnName(i));
if (path != null) {
if (path != null && isWriteablePath(path)) {
tempCounter = buildPropertySetter(setterSource, graphGuardMap, i, metaData, path, tempCounter);
}
}
Expand All @@ -171,7 +172,15 @@ private static <T> String buildMapMethodBody(Class<T> resultType, ResultSetMetaD

return source.toString();
}


private static boolean isWriteablePath(PropertyDescriptor[] path) {
return Arrays.stream(path)
.filter(pd -> pd.getWriteMethod() == null)
.findFirst()
.map(pd -> false)
.orElse(true)
;
}

private static class GraphGuardComparator implements Comparator<String> {
@Override
Expand Down Expand Up @@ -247,7 +256,6 @@ else if (!ps.isNullable() && !ps.isNeedsConversion()) {
return tempCounter;
}


private static String getNullValue(PropertySetter ps) {
if (ps.writeType.isPrimitive()) {
if (ps.writeType.equals(boolean.class)) return "false";
Expand Down
27 changes: 27 additions & 0 deletions test-src/org/dt/japper/SimpleMapTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
import java.util.List;
import java.util.Set;

import org.dt.japper.testmodel.DelegatedPartModel;
import org.dt.japper.testmodel.PartModel;
import org.dt.japper.testmodel.PartPriceModel;
import org.junit.BeforeClass;
Expand Down Expand Up @@ -239,4 +240,30 @@ public void mapPrices() throws Exception {

conn.close();
}

private static final String SQL_DELEGATED_PARTS =
" SELECT part.*, part.partno delegated_id "
+ " FROM part"
+ " ORDER BY partno"
;

/**
* Test case to reproduce the bug outlined here: https://github.com/sykesd/japper/issues/31
* We keep this test to guard against regressions.
*
* @throws Exception
*/
@Test
public void mapDelegatedParts() throws Exception {
Connection conn = testData.connect();

List<DelegatedPartModel> parts = Japper.query(conn, DelegatedPartModel.class, SQL_DELEGATED_PARTS);
assertEquals(3, parts.size());

DelegatedPartModel part = parts.get(0);
assertEquals("123456", part.getPartno());

conn.close();
}

}
50 changes: 50 additions & 0 deletions test-src/org/dt/japper/testmodel/DelegatedPartModel.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
package org.dt.japper.testmodel;

import java.math.BigDecimal;
import java.util.Map;

public class DelegatedPartModel {
private String delegatedId;

private PartModel part = new PartModel();

public String getDelegatedId() {
return delegatedId;
}

public void setDelegatedId(String delegatedId) {
this.delegatedId = delegatedId;
}

public String getPartno() {
return part.getPartno();
}

public void setPartno(String partno) {
part.setPartno(partno);
}

public String getDescription() {
return part.getDescription();
}

public void setDescription(String description) {
part.setDescription(description);
}

// NOTE: We deliberately leave off the partType property to ensure
// that an incomplete delegation does not cause an NPE
// See https://github.com/sykesd/japper/issues/31

public Map<String, BigDecimal> getFlexFields() {
return part.getFlexFields();
}

public void setFlexFields(Map<String, BigDecimal> flexFields) {
part.setFlexFields(flexFields);
}

public PartModel getPart() {
return part;
}
}

0 comments on commit aad8b64

Please sign in to comment.