To work, yes. This would be an optional means of injecting. I was thinking
some code like this (very very rough):

public void prep(DataSource source)
    throws SQLException, NoSuchMethodException,
IllegalAccessException, InvocationTargetException,
InstantiationException {

  ResultSet resultSet = source.getConnection().createStatement()
      .executeQuery("select * from User where false");
  ResultSetMetaData metaData = resultSet.getMetaData();
  Set<String> columnNames = new HashSet<>();

  for(int i = 1; i < metaData.getColumnCount(); i++) {
    columnNames.add(metaData.getColumnName(i));

  }

  Constructor<?> toUse = Arrays.stream(User.class.getDeclaredConstructors())
      .filter(c -> c.getParameterCount() == columnNames.size())
      .filter(ctr -> Arrays.stream(ctr.getParameters()).map(Parameter::getName)
          
.allMatch(columnNames::contains)).findFirst().orElse(User.class.getConstructor());

  Object entity = null;
  if(toUse != User.class.getConstructor()) {// means we found a
matching constructor
    Object[] input = new Object[toUse.getParameterCount()];
    int i = 0;
    for (Parameter parameter : toUse.getParameters()) {
      input[i++] = resultSet.getObject(parameter.getName());
    }
    entity = toUse.newInstance(input);
  }
  else {
    entity = toUse.newInstance();
  }
}


One question that comes up is which data set is the master of the match?

Do we "Select the constructor that matches the ResultSet?" or "Do we
select the result set that matches the constructor?"

Another thought is to use the existing field selection logic (find
properties on the Class) and then look for the matching constructor; which
is a very common paradigm.

Finally: An annotation specifically indicating this might also be in order.

Just getting the discussion started


On Mon, Jun 12, 2017 at 1:41 PM Vlad Mihalcea <mihalcea.v...@gmail.com>
wrote:

> Hi,
>
> Wouldn't that require all entities be compiled with?
>
> javac -parameters
>
> Vlad
>
> On Mon, Jun 12, 2017 at 10:19 PM, Christian Bongiorno <
> christian.bongio...@gmail.com> wrote:
>
>> Now that java 8 supports named parameters it becomes possible (potentially
>> preferrable) to use constructor injection instead of circumventing
>> encapsulation to set values on private fields.
>>
>> This shows itself as a potential win when integrating with Kotlin with
>> disallows the circumvention quite forcefully. Meaning: without constructor
>> injection the object needs setters. And, if it has setters then it's
>> mutable which is against best practices.
>>
>> I propose optionally using constructor injection when marshalling an
>> object
>> from data sources in a DB. I am willing to make the changes if I know they
>> can/will be incorporated.
>>
>> Thoughts? Here is the ticket
>> https://hibernate.atlassian.net/browse/HHH-11791
>>
> _______________________________________________
>> hibernate-dev mailing list
>> hibernate-dev@lists.jboss.org
>> https://lists.jboss.org/mailman/listinfo/hibernate-dev
>>
>
>
_______________________________________________
hibernate-dev mailing list
hibernate-dev@lists.jboss.org
https://lists.jboss.org/mailman/listinfo/hibernate-dev

Reply via email to