src/main/java/com/aoindustries/dbc/AutoObjectFactory.java
@Override
	public T createObject(ResultSet result) throws SQLException {
		try {
			ResultSetMetaData metaData = result.getMetaData();
			int numColumns = metaData.getColumnCount();
			int numParams = prefixParams.length + numColumns;
			Object[] params = new Object[numParams];

			// Find the candidate constructor
			List<String> warnings = null;
			Constructor<?>[] constructors = clazz.getConstructors();
		CONSTRUCTORS :
			for(Constructor<?> constructor : constructors) {
				Class<?>[] paramTypes = constructor.getParameterTypes();
				if(paramTypes.length==numParams) {
					for(int i=0;i<prefixParams.length;i++) {
						Class<?> paramType = paramTypes[i];
						if(!paramType.isAssignableFrom(prefixParams[i].getClass())) continue CONSTRUCTORS;
						params[i] = prefixParams[i];
						//System.err.println(paramType.getName()+" ? "+(params[i]==null ? "null" : params[i].getClass()));
					}
					// All remaining columns must be assignable from JDBC
					for(int c=1; c<=numColumns; c++) {
						int i = prefixParams.length + c-1;
						Class<?> paramType = paramTypes[i];
						// String first because it is commonly used
						if(paramType==String.class) {
							params[i] = result.getString(c);

						// Primitives
						} else if(paramType==Integer.TYPE) {
							int value = result.getInt(c);
							if(result.wasNull()) throw new SQLException(c+": "+metaData.getColumnName(c)+": null int");
							params[i] = value;
						} else if(paramType==Short.TYPE) {
							short value = result.getShort(c);
							if(result.wasNull()) throw new SQLException(c+": "+metaData.getColumnName(c)+": null short");
							params[i] = value;
						} else if(paramType==Boolean.TYPE) {
							boolean b = result.getBoolean(c);
							if(result.wasNull()) throw new SQLException(c+": "+metaData.getColumnName(c)+": null boolean");
							params[i] = b;
						} else if(paramType==Float.TYPE) {
							float value = result.getFloat(c);
							if(result.wasNull()) throw new SQLException(c+": "+metaData.getColumnName(c)+": null float");
							params[i] = value;
						} else if(paramType==Long.TYPE) {
							long value = result.getLong(c);
							if(result.wasNull()) throw new SQLException(c+": "+metaData.getColumnName(c)+": null long");
							params[i] = value;

						// Other types
						} else if(paramType==Date.class) {
							params[i] = result.getDate(c);
						} else if(paramType==Boolean.class) {
							boolean b = result.getBoolean(c);
							params[i] = result.wasNull() ? null : b;
						} else if(paramType==Timestamp.class) {
							params[i] = result.getTimestamp(c);
						} else if(paramType==Integer.class) {
							int value = result.getInt(c);
							params[i] = result.wasNull() ? null : value;
						} else if(paramType==Float.class) {
							float value = result.getFloat(c);
							params[i] = result.wasNull() ? null : value;
						} else if(paramType==Short.class) {
							short value = result.getShort(c);
							params[i] = result.wasNull() ? null : value;
						} else if(paramType==Long.class) {
							long value = result.getLong(c);
							params[i] = result.wasNull() ? null : value;
						} else {
							// Try to find valueOf(int) for unknown types
							Method valueOfIntMethod = getValueOfIntMethod(paramType);
							if(valueOfIntMethod!=null) {
								int value = result.getInt(c);
								if(result.wasNull()) params[i] = null;
								params[i] = valueOfIntMethod.invoke(null, value);
							} else {
								// Try to find valueOf(String) for unknown types
								Method valueOfStringMethod = getValueOfStringMethod(paramType);
								if(valueOfStringMethod!=null) {
									String value = result.getString(c);
									params[i] = result.wasNull() ? null : valueOfStringMethod.invoke(null, value);
								} else {
									if(warnings==null) warnings = new ArrayList<>();
									warnings.add("Unexpected parameter class: "+paramType.getName());
									continue CONSTRUCTORS;
								}
							}
						}
						//System.err.println(paramType.getName()+" ? "+(params[i]==null ? "null" : params[i].getClass()));
					}
					Object newInstance = constructor.newInstance(params);
					//System.err.println(newInstance.getClass().getName()+": "+newInstance);
					return clazz.cast(newInstance);
				}
			}
			StringBuilder message = new StringBuilder("Unable to find matching constructor");
			if(warnings!=null) for(String warning : warnings) message.append(EOL).append(warning);
			throw new SQLException(message.toString());
		} catch(InstantiationException | IllegalAccessException | InvocationTargetException err) {
			throw new SQLException(err);
		}
	}
}
@Override
	public T createObject(ResultSet result) throws SQLException {
		try {
			ResultSetMetaData metaData = result.getMetaData();
			int numColumns = metaData.getColumnCount();
			int numParams = prefixParams.length + numColumns;
			Object[] params = new Object[numParams];

			// Find the candidate constructor
			List<String> warnings = null;
			Constructor<?>[] constructors = clazz.getConstructors();
		CONSTRUCTORS :
			for(Constructor<?> constructor : constructors) {
				Class<?>[] paramTypes = constructor.getParameterTypes();
				if(paramTypes.length==numParams) {
					for(int i=0;i<prefixParams.length;i++) {
						Class<?> paramType = paramTypes[i];
						if(!paramType.isAssignableFrom(prefixParams[i].getClass())) continue CONSTRUCTORS;
						params[i] = prefixParams[i];
						//System.err.println(paramType.getName()+" ? "+(params[i]==null ? "null" : params[i].getClass()));
					}
					// All remaining columns must be assignable from JDBC
					for(int c=1; c<=numColumns; c++) {
						int i = prefixParams.length + c-1;
						Class<?> paramType = paramTypes[i];
						// String first because it is commonly used
						if(paramType==String.class) {
							params[i] = result.getString(c);

						// Primitives
						} else if(paramType==Integer.TYPE) {
							int value = result.getInt(c);
							if(result.wasNull()) throw new SQLException(c+": "+metaData.getColumnName(c)+": null int");
							params[i] = value;
						} else if(paramType==Short.TYPE) {
							short value = result.getShort(c);
							if(result.wasNull()) throw new SQLException(c+": "+metaData.getColumnName(c)+": null short");
							params[i] = value;
						} else if(paramType==Boolean.TYPE) {
							boolean b = result.getBoolean(c);
							if(result.wasNull()) throw new SQLException(c+": "+metaData.getColumnName(c)+": null boolean");
							params[i] = b;
						} else if(paramType==Float.TYPE) {
							float value = result.getFloat(c);
							if(result.wasNull()) throw new SQLException(c+": "+metaData.getColumnName(c)+": null float");
							params[i] = value;
						} else if(paramType==Long.TYPE) {
							long value = result.getLong(c);
							if(result.wasNull()) throw new SQLException(c+": "+metaData.getColumnName(c)+": null long");
							params[i] = value;

						// Other types
						} else if(paramType==Date.class) {
							params[i] = result.getDate(c);
						} else if(paramType==Boolean.class) {
							boolean b = result.getBoolean(c);
							params[i] = result.wasNull() ? null : b;
						} else if(paramType==Timestamp.class) {
							params[i] = result.getTimestamp(c);
						} else if(paramType==Integer.class) {
							int value = result.getInt(c);
							params[i] = result.wasNull() ? null : value;
						} else if(paramType==Float.class) {
							float value = result.getFloat(c);
							params[i] = result.wasNull() ? null : value;
						} else if(paramType==Short.class) {
							short value = result.getShort(c);
							params[i] = result.wasNull() ? null : value;
						} else if(paramType==Long.class) {
							long value = result.getLong(c);
							params[i] = result.wasNull() ? null : value;
						} else {
							// Try to find valueOf(int) for unknown types
							Method valueOfIntMethod = getValueOfIntMethod(paramType);
							if(valueOfIntMethod!=null) {
								int value = result.getInt(c);
								if(result.wasNull()) params[i] = null;
								params[i] = valueOfIntMethod.invoke(null, value);
							} else {
								// Try to find valueOf(String) for unknown types
								Method valueOfStringMethod = getValueOfStringMethod(paramType);
								if(valueOfStringMethod!=null) {
									String value = result.getString(c);
									params[i] = result.wasNull() ? null : valueOfStringMethod.invoke(null, value);
								} else {
									if(warnings==null) warnings = new ArrayList<>();
									warnings.add("Unexpected parameter class: "+paramType.getName());
									continue CONSTRUCTORS;
								}
							}
						}
						//System.err.println(paramType.getName()+" ? "+(params[i]==null ? "null" : params[i].getClass()));
					}
					Object newInstance = constructor.newInstance(params);
					//System.err.println(newInstance.getClass().getName()+": "+newInstance);
					return clazz.cast(newInstance);
				}
			}
			StringBuilder message = new StringBuilder("Unable to find matching constructor");
			if(warnings!=null) for(String warning : warnings) message.append(EOL).append(warning);
			throw new SQLException(message.toString());
		} catch(InstantiationException | IllegalAccessException | InvocationTargetException err) {
			throw new SQLException(err);
		}
	}
}
@ Override public T createObject ( ResultSet result ) throws SQLException { try { ResultSetMetaData metaData = result . getMetaData ( ) ; int numColumns = metaData . getColumnCount ( ) ; int numParams = prefixParams . length + numColumns ; Object [ ] params = new Object [ numParams ] ; // Find the candidate constructor List < String > warnings = null ; Constructor < ? > [ ] constructors = clazz . getConstructors ( ) ; CONSTRUCTORS : for ( Constructor < ? > constructor : constructors ) { Class < ? > [ ] paramTypes = constructor . getParameterTypes ( ) ; if ( paramTypes . length == numParams ) { for ( int i = 0 ; i < prefixParams . length ; i ++ ) { Class < ? > paramType = paramTypes [ i ] ; if ( ! paramType . isAssignableFrom ( prefixParams [ i ] . getClass ( ) ) ) continue CONSTRUCTORS ; params [ i ] = prefixParams [ i ] ; //System.err.println(paramType.getName()+" ? "+(params[i]==null ? "null" : params[i].getClass())); } // All remaining columns must be assignable from JDBC for ( int c = 1 ; c <= numColumns ; c ++ ) { int i = prefixParams . length + c - 1 ; Class < ? > paramType = paramTypes [ i ] ; // String first because it is commonly used if ( paramType == String . class ) { params [ i ] = result . getString ( c ) ; // Primitives } else if ( paramType == Integer . TYPE ) { int value = result . getInt ( c ) ; if ( result . wasNull ( ) ) throw new SQLException ( c + ": " + metaData . getColumnName ( c ) + ": null int" ) ; params [ i ] = value ; } else if ( paramType == Short . TYPE ) { short value = result . getShort ( c ) ; if ( result . wasNull ( ) ) throw new SQLException ( c + ": " + metaData . getColumnName ( c ) + ": null short" ) ; params [ i ] = value ; } else if ( paramType == Boolean . TYPE ) { boolean b = result . getBoolean ( c ) ; if ( result . wasNull ( ) ) throw new SQLException ( c + ": " + metaData . getColumnName ( c ) + ": null boolean" ) ; params [ i ] = b ; } else if ( paramType == Float . TYPE ) { float value = result . getFloat ( c ) ; if ( result . wasNull ( ) ) throw new SQLException ( c + ": " + metaData . getColumnName ( c ) + ": null float" ) ; params [ i ] = value ; } else if ( paramType == Long . TYPE ) { long value = result . getLong ( c ) ; if ( result . wasNull ( ) ) throw new SQLException ( c + ": " + metaData . getColumnName ( c ) + ": null long" ) ; params [ i ] = value ; // Other types } else if ( paramType == Date . class ) { params [ i ] = result . getDate ( c ) ; } else if ( paramType == Boolean . class ) { boolean b = result . getBoolean ( c ) ; params [ i ] = result . wasNull ( ) ? null : b ; } else if ( paramType == Timestamp . class ) { params [ i ] = result . getTimestamp ( c ) ; } else if ( paramType == Integer . class ) { int value = result . getInt ( c ) ; params [ i ] = result . wasNull ( ) ? null : value ; } else if ( paramType == Float . class ) { float value = result . getFloat ( c ) ; params [ i ] = result . wasNull ( ) ? null : value ; } else if ( paramType == Short . class ) { short value = result . getShort ( c ) ; params [ i ] = result . wasNull ( ) ? null : value ; } else if ( paramType == Long . class ) { long value = result . getLong ( c ) ; params [ i ] = result . wasNull ( ) ? null : value ; } else { // Try to find valueOf(int) for unknown types Method valueOfIntMethod = getValueOfIntMethod ( paramType ) ; if ( valueOfIntMethod != null ) { int value = result . getInt ( c ) ; if ( result . wasNull ( ) ) params [ i ] = null ; params [ i ] = valueOfIntMethod . invoke ( null , value ) ; } else { // Try to find valueOf(String) for unknown types Method valueOfStringMethod = getValueOfStringMethod ( paramType ) ; if ( valueOfStringMethod != null ) { String value = result . getString ( c ) ; params [ i ] = result . wasNull ( ) ? null : valueOfStringMethod . invoke ( null , value ) ; } else { if ( warnings == null ) warnings = new ArrayList <> ( ) ; warnings . add ( "Unexpected parameter class: " + paramType . getName ( ) ) ; continue CONSTRUCTORS ; } } } //System.err.println(paramType.getName()+" ? "+(params[i]==null ? "null" : params[i].getClass())); } Object newInstance = constructor . newInstance ( params ) ; //System.err.println(newInstance.getClass().getName()+": "+newInstance); return clazz . cast ( newInstance ) ; } } StringBuilder message = new StringBuilder ( "Unable to find matching constructor" ) ; if ( warnings != null ) for ( String warning : warnings ) message . append ( EOL ) . append ( warning ) ; throw new SQLException ( message . toString ( ) ) ; } catch ( InstantiationException | IllegalAccessException | InvocationTargetException err ) { throw new SQLException ( err ) ; } } }
Creates one object from the current values in the ResultSet.  Looks for a
constructor that is assignable to the prefixParams and the result set values.
The constructor must exactly match the number of prefixParams plus the
result set.
Creates one object from the current values in the ResultSet . Looks for a constructor that is assignable to the prefixParams and the result set values . The constructor must exactly match the number of prefixParams plus the result set .