Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

@NamedNativeQuery - How can I bind it to a repository method?

Tags:

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!
like image 972
ram Avatar asked Jul 02 '17 14:07

ram


People also ask

How can you configure native SQL query for a query method in a repository?

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.

Which is better JPQL or native query?

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.


1 Answers

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.

like image 67
Grant Lay Avatar answered Oct 16 '22 18:10

Grant Lay