Add support for class based projections [DATACMNS-1013]
Thomas Darimont opened DATACMNS-1013 and commented
Currently Spring Data Repositories support dynamic proxy based entity projections that expose persistent properties based on property declarations on an interface.
In some occasions it would be handy to work with class based projections directly, e.g. to avoid overhead (memory, reflective method invocations), less garbage creation etc.
It seems to be enough to add an additional converter to the ConversionService instance in: org.springframework.data.repository.query.ResultProcessor.ProjectingConverter which dynamically checks for compatible projection type and creates the projection instance and copies the mapped properties over to the new instance.
I created a small PoC as a gist: https://gist.github.com/thomasdarimont/c59ac8679aae04be8ce0cd73af10b59e
It effectively allows to map the following entity
@Entity
@Data
class Customer {
@Id
Long id;
String firstname;
String lastname;
}
Via this repository:
interface CustomerRepository extends JpaRepository<Customer, Long> {
List<PersonName> findAllCustomerNamesBy();
}
onto this "projection type"
@Data
class PersonName {
String firstname;
String lastname;
}
No further details from DATACMNS-1013
Oliver Drotbohm commented
That's actually already supported as shown in the example here. I guess the point you missed is that classes don't actually use the projection factory code path but are translated into e.g. constructor expressions in JPA or just handed to the converter in MongoDB.
Anything I miss?
Thomas Darimont commented
Ah thanks, I missed that it works if there is a constructor.
So declaring the fields of PersonName final works when the ctor is generated by lombok.
However sometimes you don't have a constructor on the projection type and you cannot simply add one. In those cases it would be helpful to have support for a property / field based mapping as described above.
Btw. would be nice if the error message would state the fact that a constructor was missing instead of just saying:
ConverterNotFoundException: No converter found capable of converting from type [demo.Customer] to type [demo.PersonName].
If you would like us to look at this issue, please provide the requested information. If the information is not provided within the next 7 days this issue will be closed.
Our DTO-based projections in MongoDB, Neo4j, and Cassandra support property-population already. JPA remains as a module where we should provide a similar level of convenience via https://github.com/spring-projects/spring-data-jpa/issues/2327.