I am using Spring
+ Hibernate
and I have a particular case where I need to obtain (a list of) non-Entity
objects as a result of the query.
I decided to use @ConstructorResult
in @SqlResultSetMapping
and refer to this mapping in @NamedNativeQuery
, as mentioned here and here.
However, in all examples using named native queries, they obtain EntityManager
instance via @PersistenceContext
and call createNativeQuery
on it, providing the name
of @NamedNativeQuery
as parameter to that call, as seen in this answer.
How can I map a method declared in a repository interface
to a particular @NamedNativeQuery
? My attempt was to use EntityName.MethodNameInRepository
or MethodNameInRepository
as the name
of @NamedNativeQuery
, but no luck.
Here is my simplified code:
@Entity(name = "AdDailyData")
@SqlResultSetMapping(
name="RevenueByAppAndDayMapping",
classes=@ConstructorResult(
targetClass=RevenueByAppAndDay.class,
columns={@ColumnResult(name="country_code"),
@ColumnResult(name="revenue", type=Double.class),
@ColumnResult(name="currency")}))
@NamedNativeQuery(
name="AdDailyData.aggregateRevenue",
query="SELECT country_code, sum(earnings) as revenue, currency "
+ "FROM ad_daily_data, pseudo_app, app "
+ "WHERE ad_daily_data.pseudo_app_id=pseudo_app.id AND pseudo_app.app_id=app.id AND app.id=:appId and ad_daily_data.day = :day "
+ "GROUP BY country_code, currency "
+ "ORDER BY country_code ASC",
resultSetMapping="RevenueByAppAndDayMapping")
public class AdDailyDataEntity {
// fields, getters, setters etc.
public static interface Repository extends JpaRepository<AdDailyDataEntity, Long> {
public List<RevenueByAppAndDay> aggregateRevenue(@Param("appId") long appId, @Param("day") LocalDate day);
}
}
Here is my non-Entity
class.
public class RevenueByAppAndDay {
private String countryCode;
private Double earnings;
private String currency;
public RevenueByAppAndDay(String countryCode, Double earnings, String currency) {
this.countryCode = countryCode;
this.earnings = earnings;
this.currency = currency;
}
public String getCountryCode() {
return countryCode;
}
public Double getEarnings() {
return earnings;
}
public String getCurrency() {
return currency;
}
}
Any kind of help is highly appreciated.
EDIT: The end of the stack trace is as follows:
Caused by: org.springframework.data.mapping.PropertyReferenceException: No property aggregateRevenue found for type AdDailyDataEntity!
We can use @Query annotation to specify a query within a repository. Following is an example. In this example, we are using native query, and set an attribute nativeQuery=true in Query annotation to mark the query as native. We've added custom methods in Repository in JPA Custom Query chapter.
NativeQuery We must always consider if a NativeQuery is the only option. Most of the time, a good JPQL Query can fulfill our needs and most importantly, maintain a level of abstraction from the actual database implementation. Using NativeQuery doesn't necessarily mean locking ourselves to one specific database vendor.
The name
value on the @NamedNativeQuery
needs to be set to "AdDailyDataEntity.aggregateRevenue"
. The first part (before the dot) needs to match the entity class name.
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