web-dev-qa-db-fra.com

@NamedNativeQuery - Comment puis-je le lier à une méthode de référentiel?

J'utilise Spring + Hibernate et j'ai un cas particulier où j'ai besoin d'obtenir (une liste) d'objets nonEntity à la suite de la requête.

J'ai décidé d'utiliser @ConstructorResult Dans @SqlResultSetMapping Et de faire référence à ce mappage dans @NamedNativeQuery, Comme mentionné ici et ici .

Cependant, dans tous les exemples utilisant des requêtes natives nommées, ils obtiennent une instance de EntityManager via @PersistenceContext Et appellent createNativeQuery dessus, fournissant le name de @NamedNativeQuery comme paramètre de cet appel, comme indiqué dans la réponse this .

Comment puis-je mapper une méthode déclarée dans un référentiel interface à un @NamedNativeQuery Particulier? J'ai tenté d'utiliser EntityName.MethodNameInRepository Ou MethodNameInRepository comme name de @NamedNativeQuery, Mais pas de chance.

Voici mon code simplifié:

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

    }

}

Voici ma classe non -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;
    }

}

Toute aide est très appréciée.

EDIT: La fin de la trace de pile est la suivante:

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

La valeur name sur le @NamedNativeQuery doit être défini sur "AdDailyDataEntity.aggregateRevenue". La première partie (avant le point) doit correspondre au nom de la classe d'entité.

13
Grant Lay

Bien que la réponse soit correcte, pour quelqu'un arrivé ici pour des questions similaires, cela fonctionne pour moi sans utiliser @NamedNativeQuery:

public class Example {

private Long someProperty;
// getters and setters
}

Pour appeler une requête ou une procédure stockée et remplir mon objet:

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

}

Je sais que c'est une autre approche et le code est découplé, mais nous obtenons le même résultat.

J'espère que cela peut être utile pour quelqu'un. Cordialement.

0
Hizmarck