[hibernate-dev] HHH-11791

Christian Bongiorno christian.bongiorno at gmail.com
Mon Jun 12 17:47:59 EDT 2017


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.vlad at 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.bongiorno at 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 at lists.jboss.org
>> https://lists.jboss.org/mailman/listinfo/hibernate-dev
>>
>
>


More information about the hibernate-dev mailing list