[hibernate-issues] [JIRA] (HSEARCH-3927) Projection to a DTO/JavaBean/etc.

Yoann Rodière (JIRA) jira at hibernate.atlassian.net
Tue May 26 07:35:45 EDT 2020


Yoann Rodière ( https://hibernate.atlassian.net/secure/ViewProfile.jspa?accountId=557058%3A58fa1ced-171a-4c00-97e8-5d70d442cc4b ) *created* an issue

Hibernate Search ( https://hibernate.atlassian.net/browse/HSEARCH?atlOrigin=eyJpIjoiNTYzYTJlZDM2NDRiNDNlN2ExMDRmZDJkNDU1OWU4NWYiLCJwIjoiaiJ9 ) / New Feature ( https://hibernate.atlassian.net/browse/HSEARCH-3927?atlOrigin=eyJpIjoiNTYzYTJlZDM2NDRiNDNlN2ExMDRmZDJkNDU1OWU4NWYiLCJwIjoiaiJ9 ) HSEARCH-3927 ( https://hibernate.atlassian.net/browse/HSEARCH-3927?atlOrigin=eyJpIjoiNTYzYTJlZDM2NDRiNDNlN2ExMDRmZDJkNDU1OWU4NWYiLCJwIjoiaiJ9 ) Projection to a DTO/JavaBean/etc. ( https://hibernate.atlassian.net/browse/HSEARCH-3927?atlOrigin=eyJpIjoiNTYzYTJlZDM2NDRiNDNlN2ExMDRmZDJkNDU1OWU4NWYiLCJwIjoiaiJ9 )

Issue Type: New Feature Assignee: Unassigned Components: engine Created: 26/May/2020 04:35 AM Fix Versions: 6.0.0-Bonus-backlog Priority: Major Reporter: Yoann Rodière ( https://hibernate.atlassian.net/secure/ViewProfile.jspa?accountId=557058%3A58fa1ced-171a-4c00-97e8-5d70d442cc4b )

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

public class TitleAndGenre {
   public final String title;
   public final Genre genre;
   public TitleAndGenre( String title, Genre genre) {
       ...
   }
}

List<TitleAndGenre> hits = searchSession.search( Book.class )
		.select( f -> f.composite(
				TitleAndGenre:: new ,
				f.field( "title" , String.class ),
				f.field( "genre" , Genre.class )
		) )
		.where( f -> f.matchAll() )
		.fetchHits( 20 );

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.

// Project on fields "title" and "genre"
.select( f -> f.object( TitleAndGenre.class ) )
// Maybe also add a shorthand
.select( TitleAndGenre.class )
// Project on fields "someAssociation.title" and "someAssociation.genre"
.select( f -> f.object( "someAssociation" , TitleAndGenre.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
* 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 or through setters? 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.

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.

( https://hibernate.atlassian.net/browse/HSEARCH-3927#add-comment?atlOrigin=eyJpIjoiNTYzYTJlZDM2NDRiNDNlN2ExMDRmZDJkNDU1OWU4NWYiLCJwIjoiaiJ9 ) Add Comment ( https://hibernate.atlassian.net/browse/HSEARCH-3927#add-comment?atlOrigin=eyJpIjoiNTYzYTJlZDM2NDRiNDNlN2ExMDRmZDJkNDU1OWU4NWYiLCJwIjoiaiJ9 )

Get Jira notifications on your phone! Download the Jira Cloud app for Android ( https://play.google.com/store/apps/details?id=com.atlassian.android.jira.core&referrer=utm_source%3DNotificationLink%26utm_medium%3DEmail ) or iOS ( https://itunes.apple.com/app/apple-store/id1006972087?pt=696495&ct=EmailNotificationLink&mt=8 ) This message was sent by Atlassian Jira (v1001.0.0-SNAPSHOT#100127- sha1:dccb6b5 )
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.jboss.org/pipermail/hibernate-issues/attachments/20200526/880ab5c3/attachment.html 


More information about the hibernate-issues mailing list