mirror of
https://github.com/moparisthebest/JdbcMapper
synced 2024-11-24 01:52:22 -05:00
Call super(Connection) if it exists, tweak cannot find Constructor error message
This commit is contained in:
parent
50ebcc84cb
commit
f68fd749e3
@ -2,6 +2,7 @@ package com.moparisthebest.jdbc.codegen;
|
||||
|
||||
import com.moparisthebest.jdbc.CompilingRowToObjectMapper;
|
||||
import com.moparisthebest.jdbc.MapperException;
|
||||
import com.moparisthebest.jdbc.RowToObjectMapper;
|
||||
import com.moparisthebest.jdbc.TypeMappingsFactory;
|
||||
|
||||
import javax.lang.model.element.*;
|
||||
@ -95,7 +96,7 @@ public class CompileTimeRowToObjectMapper {
|
||||
*/
|
||||
outer:
|
||||
for(final Element e : methodsAndConstructors) {
|
||||
if(e.getKind() == ElementKind.CONSTRUCTOR && e.getModifiers().contains(Modifier.PUBLIC)) {
|
||||
if(e.getKind() == ElementKind.CONSTRUCTOR && e.getModifiers().contains(Modifier.PUBLIC)) { // todo: public normally, but also package-private if same package, or protected if it's a sub-class of super...
|
||||
final List<? extends VariableElement> params = ((ExecutableElement)e).getParameters();
|
||||
if(params.isEmpty())
|
||||
defaultConstructor = true;
|
||||
@ -134,7 +135,8 @@ public class CompileTimeRowToObjectMapper {
|
||||
_fieldOrder = null; // didn't successfully finish
|
||||
this.resultSetConstructor = resultSetConstructor;
|
||||
if(!resultSetConstructor && !defaultConstructor && !paramConstructor && _columnCount > 2 && componentType == null)
|
||||
throw new MapperException("Exception when trying to get constructor for : "+_returnTypeClass.toString() + " Must have default no-arg constructor or one that takes a single ResultSet.");
|
||||
throw new MapperException("Exception when trying to get constructor for : "+_returnTypeClass.toString() + " Must have default no-arg constructor, one that takes a single ResultSet, or one that takes parameters named like the query columns (in any order):\n" +
|
||||
RowToObjectMapper.keysToString(keys)+ "\nRequires compilation with -parameters argument if source isn't being compiled this pass, beware Bug ID: JDK-8191074 with jdk8, fixed in 9+");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -15,6 +15,7 @@ import javax.tools.Diagnostic;
|
||||
import java.io.*;
|
||||
import java.sql.Blob;
|
||||
import java.sql.Clob;
|
||||
import java.sql.Connection;
|
||||
import java.sql.SQLException;
|
||||
import java.util.*;
|
||||
import java.util.regex.Matcher;
|
||||
@ -65,7 +66,7 @@ public class JdbcMapperProcessor extends AbstractProcessor {
|
||||
return messager;
|
||||
}
|
||||
|
||||
static TypeMirror sqlExceptionType, stringType, numberType, utilDateType, readerType, clobType, jdbcMapperType,
|
||||
static TypeMirror sqlExceptionType, stringType, numberType, utilDateType, readerType, clobType, connectionType, jdbcMapperType,
|
||||
byteArrayType, inputStreamType, fileType, blobType, sqlArrayType, collectionType, calendarType, cleanerType, enumType;
|
||||
//IFJAVA8_START
|
||||
static TypeMirror instantType, localDateTimeType, localDateType, localTimeType, zonedDateTimeType, offsetDateTimeType, offsetTimeType;
|
||||
@ -97,6 +98,7 @@ public class JdbcMapperProcessor extends AbstractProcessor {
|
||||
utilDateType = elements.getTypeElement(java.util.Date.class.getCanonicalName()).asType();
|
||||
readerType = elements.getTypeElement(Reader.class.getCanonicalName()).asType();
|
||||
clobType = elements.getTypeElement(Clob.class.getCanonicalName()).asType();
|
||||
connectionType = elements.getTypeElement(Connection.class.getCanonicalName()).asType();
|
||||
jdbcMapperType = elements.getTypeElement(JdbcMapper.class.getCanonicalName()).asType();
|
||||
inputStreamType = elements.getTypeElement(InputStream.class.getCanonicalName()).asType();
|
||||
fileType = elements.getTypeElement(File.class.getCanonicalName()).asType();
|
||||
@ -234,10 +236,19 @@ public class JdbcMapperProcessor extends AbstractProcessor {
|
||||
w.write(className);
|
||||
w.write("() throws SQLException {\n\t\tthis(_conFactory);\n\t}\n");
|
||||
}
|
||||
|
||||
w.write("\n\tprivate ");
|
||||
w.write(className);
|
||||
w.write("(final Connection conn, final boolean closeConn) {\n");
|
||||
if(hasSuperConstructorTakesConnection(genClass))
|
||||
w.write("\t\tsuper(conn);\n");
|
||||
w.write("\t\tthis.conn = conn;\n\t\tthis.closeConn = closeConn;\n\t\tif (this.conn == null)\n" +
|
||||
"\t\t\tthrow new NullPointerException(\"Connection needs to be non-null for JdbcMapper...\");\n\t}\n"
|
||||
);
|
||||
|
||||
w.write("\n\tpublic ");
|
||||
w.write(className);
|
||||
w.write("(Connection conn) {\n\t\tthis.conn = conn;\n\t\tthis.closeConn = false;\n\t\tif (this.conn == null)\n" +
|
||||
"\t\t\tthrow new NullPointerException(\"Connection needs to be non-null for JdbcMapper...\");\n\t}\n" +
|
||||
w.write("(Connection conn) {\n\t\tthis(conn, false);\n\t}\n" +
|
||||
"\n\tpublic Connection getConnection() {\n\t\treturn this.conn;\n\t}\n"
|
||||
);
|
||||
|
||||
@ -541,8 +552,7 @@ public class JdbcMapperProcessor extends AbstractProcessor {
|
||||
// and we can create constructors that set closeConn to true!
|
||||
w.write("\n\tpublic ");
|
||||
w.write(className);
|
||||
w.write("(final Factory<Connection> connectionFactory) throws SQLException {\n\t\tthis.conn = connectionFactory.create();\n\t\tthis.closeConn = true;\n\t\tif (this.conn == null)\n" +
|
||||
"\t\t\tthrow new NullPointerException(\"Connection needs to be non-null for JdbcMapper...\");\n\t}\n"
|
||||
w.write("(final Factory<Connection> connectionFactory) throws SQLException {\n\t\tthis(connectionFactory.create(), true);\n\t}\n"
|
||||
);
|
||||
|
||||
w.write("\n\tpublic ");
|
||||
@ -950,4 +960,16 @@ public class JdbcMapperProcessor extends AbstractProcessor {
|
||||
tryClose(pw);
|
||||
}
|
||||
}
|
||||
|
||||
public boolean hasSuperConstructorTakesConnection(final TypeElement genClass) {
|
||||
final List<? extends Element> methodsAndConstructors = genClass.getEnclosedElements();
|
||||
for(final Element e : methodsAndConstructors) {
|
||||
if (e.getKind() == ElementKind.CONSTRUCTOR && !e.getModifiers().contains(Modifier.PRIVATE)) {
|
||||
final List<? extends VariableElement> params = ((ExecutableElement)e).getParameters();
|
||||
if(params.size() == 1 && types.isSameType(params.get(0).asType(), connectionType))
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
@ -197,7 +197,11 @@ public class RowToObjectMapper<K, T> extends AbstractRowMapper<K, T> {
|
||||
// if column count is 2 or less, it might map directly to a type like a Long or something, or be a map which does
|
||||
// or if componentType is non-null, then we want an array like Long[] or String[]
|
||||
if (_columnCount > 2 && componentType == null)
|
||||
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);
|
||||
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"
|
||||
//IFJAVA8_START
|
||||
+ ", or one that takes parameters named like the query columns (in any order):\n" + keysToString(keys) + "\nRequires compilation with -parameters argument, beware Bug ID: JDK-8191074 with jdk8, fixed in 9+"
|
||||
//IFJAVA8_END
|
||||
, e1);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -208,6 +212,24 @@ public class RowToObjectMapper<K, T> extends AbstractRowMapper<K, T> {
|
||||
this.constructorLoaded = true;
|
||||
}
|
||||
|
||||
public static String keysToString(final String[] a) {
|
||||
if (a == null)
|
||||
return "null";
|
||||
|
||||
int iMax = a.length - 1;
|
||||
if (iMax == 0)
|
||||
return "[]";
|
||||
|
||||
StringBuilder b = new StringBuilder();
|
||||
b.append('[');
|
||||
for (int i = 1; ; i++) {
|
||||
b.append(String.valueOf(a[i]));
|
||||
if (i == iMax)
|
||||
return b.append(']').toString();
|
||||
b.append(", ");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This returns a new instance of the Map class required by Map<String, Object>[]
|
||||
* It lives in it's own method to minimize suppressed warnings and allow subclasses to override methods,
|
||||
|
@ -118,5 +118,6 @@ try(QueryMapper qm = new QueryMapper("java:/comp/env/jdbc/testPool", new ResultS
|
||||
TODO
|
||||
----
|
||||
|
||||
* Binding of Enum to String by default
|
||||
* sql other than select return boolean, int > 0 ?
|
||||
* DOCUMENTATION!!!!!
|
||||
* sql other than select return boolean, int > 0 ?
|
||||
* @RunInTransaction void support
|
Loading…
Reference in New Issue
Block a user