web-dev-qa-db-ja.com

@NamedNativeQuery-リポジトリメソッドにバインドする方法を教えてください。

私はSpring + Hibernateを使用していますが、クエリの結果として非Entityオブジェクト(のリスト)を取得する必要がある特定のケースがあります。

私は@ConstructorResult@SqlResultSetMappingを使用し、@NamedNativeQueryでこのマッピングを参照することにしました。これは、 こちらです。ここに

ただし、名前付きネイティブクエリを使用するすべての例では、EntityManagerインスタンスを@PersistenceContext経由で取得し、createNativeQueryを呼び出してname of @NamedNativeQueryを提供します。 this の回答に見られるように、その呼び出しのパラメータとして。

リポジトリinterfaceで宣言されたメソッドを特定の@NamedNativeQueryにマップするにはどうすればよいですか?私の試みは、EntityName.MethodNameInRepositoryMethodNameInRepositoryとして@NamedNativeQueryまたはnameを使用することでしたが、うまくいきませんでした。

これが私の簡単なコードです:

@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);

    }

}

これが私の非Entityクラスです。

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;
    }

}

どんな種類の助けも大歓迎です。

EDIT:スタックトレースの終わりは次のとおりです。

Caused by: org.springframework.data.mapping.PropertyReferenceException: No property aggregateRevenue found for type AdDailyDataEntity!
14
ram

@NamedNativeQueryname値は"AdDailyDataEntity.aggregateRevenue"に設定する必要があります。最初の部分(ドットの前)は、エンティティークラス名と一致する必要があります。

13
Grant Lay

答えは正しいですが、誰かがここに到着して似たような言い回しをするのであれば、@ NamedNativeQueryを使わなくてもこれはうまくいきます。

public class Example {

private Long someProperty;
// getters and setters
}

クエリまたはストアドプロシージャを呼び出してオブジェクトを設定するには:

@Repository
public interface ExampleRepository extends 
JpaRepository<Example,Long> {

/**
 * Search Example by someProperty
 *
 * @param property
 * @return
 */
@Query( nativeQuery = true, value = "SELECT * FROM public.my_stored_procedure(:property)")
List<Example> findByProperty(@Param("property") Long property);

}

これは別のアプローチであり、コードが分離されていることは知っていますが、同じ結果が得られます。

私はそれが誰かのために役立つことを願っています。よろしく。

0
Hizmarck