Projection to a DTO/JavaBean/etc.

Description

Currently the only way to build an object for each hit is to define a composite projection by hand:

That's fine when there are just two or three fields involved, but it can quickly become very verbose, especially if nested objects must be created.

We should introduce a way to automate the process. The user would simply define a class, and ask that we project to that class.

We would need to:

  • Discover the constructors of the given type

  • Enforce that there is only one constructor

  • Discover the constructor parameters (name and type)

  • Create one field projection per constructor parameter, assuming the parameter name is the field name

  • Create a composite projection to aggregate the field projections

  • Return the composite projection

Several things will have to be considered:

  • Can we assume that the name of constructor parameters is always available? IIRC, a specific flag is needed at compilation time, but maybe it's no longer the case in recent versions of Java. See Hibernate Validator.

  • Do we want to pass the field values through the constructor, through setters, through a builder (for example like this one)? Maybe offer the choice?

  • We will probably need a way to handle "nested" projection classes, i.e. have a parameter of the projection class constructor whose type is also a projection class. In this case the parameter name would be the name of an object field.

  • As a first step, we can expect that projections to multi-valued fields are always represented by a List<Something>, but eventually we may need to support Set, arrays, SortedSet/NavigableSet (comparator/natural order), or even Map.

Follow-up ideas:

  • Maybe we'll need a way to pre-declare such "projection classes", so that they can be validated on bootstrap, and more importantly so that they are discovered when we can use reflection (in native mode, we can't use reflection after bootstrap).

  • What about records? (Java 14+, I believe)

  • This feature would be very useful to introduce a standalone Elasticsearch mapper, where Elasticsearch is the primary source of truth and thus entities have to be created from Elasticsearch documents.

Environment

None

Assignee

Yoann Rodière

Reporter

Yoann Rodière

Labels

None

Suitable for new contributors

None

Pull Request

None

Feedback Requested

None

Components

Fix versions

Priority

Major
Configure