I want to make a complex query and map the result into a DTO. The DTO is below:
@Value(staticConstructor = "of")
public class TotalsDto {
LocalDate date;
long totals;
long totalPerCategory;
int categoryId;
String categoryName;
}
My repository interface is extending from JpaRepository
. This is throwing an IllegalArgumentException: Not a managed type
, because TotalsDto
is not an Entity itself.
The repository is:
@Repository
public interface TotalsRepository extends JpaRepository<TotalsDto, Integer> {
@Query(value = "SELECT ...", nativeQuery = true)
List<TotalsDto> getTotals(params...);
}
The query is getting data from other entities to build the DTO.
Any way to map every column to DTO? I tried to map it with the query below but it still getting Not a managed class
.
SELECT my.package.TotalsDto.of(column1, subqueryResult1, subqueryResult2...)
The easiest way to use this projection is to define your query as a @NamedNativeQuery and assign an @SqlResultSetMapping that defines a constructor result mapping. The instantiation of the DTO objects is then handled by the underlying persistence provider when Spring Data JPA executes the @NamedNativeQuery.
The easiest way to map a query result to an entity is to provide the entity class as a parameter to the createNativeQuery(String sqlString, Class resultClass) method of the EntityManager and use the default mapping. The following snippet shows how this is done with a very simple query.
You define a DTO projection in a CriteriaQuery in a pretty similar way as you do in JPQL. But instead of using the new keyword to specify the constructor call in a query String, you call the construct method on the CriteriaBuilder with a reference to the DTO class and a List of constructor parameters.
1) Make TotalsDto
an interface
2) Create getters:
public interface TotalsDto{
long getTotals();
int getCategoryId();
...
}
Spring Data Jpa will then automatically create / fill you result object.
More on the subject here
The first type argument to Repository
(or JpaRepository
) must be a managed entity. Therefore, JpaRepository<TotalsDto, Integer>
is invalid, as TotalsDto
is not a managed entity. Change TotalsDto
to a projection interface like @MaciejKowalski has suggested, and then pass a JPA entity to Repository
as the first type argument, say, Repository<Order, Integer>
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With