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!
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é.
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.