[英]How to receive a set from Spring Data JPA NativeQuery? [results in NotReadablePropertyException]
首先:我在Java 8中使用Spring-Boot Data JPA
。
我的數據庫中有一個表,我的實體定義如下:
@Entity
@Table(name="ITEMHOURS")
public class ItemHoursEntity {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "ID")
private int id;
@Column(name = "YEAR", nullable = false)
private String year;
@Enumerated(EnumType.STRING)
@Column(name = "STATE", nullable = false)
private TypeEnum type;
@Column(name = "HOURVALUE", nullable = false)
private int hourValue = 0;
@ManyToOne(cascade = CascadeType.MERGE)
@JoinColumn(name = "ITEM_ID")
private MyItem item;
//.. some more columns, getters, setters...
}
現在我得到以下選擇返回此結構:
-----------------------
| YEAR | Value | Type |
-----------------------
@Query(value = "Select year as year, sum(hourvalue) as value, state as type from ITEMHOURS h where item_id = :item_id group by h.year, h.state", nativeQuery = true)
public Optional<Collection<TotalValuesProjection>> getYearTotalsForStateByItem(@Param("item_id") int item_id);
它在MySQL Workbench
運行良好。 結果,我聽說我應該通過使用投影來獲取與默認ItemHoursEntity
不同的結果,所以我嘗試創建以下內容:
@Projection(types = { ItemHoursEntity.class })
public interface TotalValuesProjection {
public String getYear();
public int getValue();
public HourTypeEnum getType();
}
現在在我的service
類中,我嘗試以下方法:
@Override
public List<ExtendedDataPasser<String, Integer, String>> getTotalAndYearHourValuesForItem(int itemId) {
Optional<Collection<TotalValuesProjection>> projectionOptional = this.hoursRepository.getYearTotalsForStateByItem(itemId);
List<ExtendedDataPasser<String, Integer, String>> entityList = new ArrayList<ExtendedDataPasser<String, Integer, String>>();
projectionOptional.orElseGet(() -> new ArrayList<TotalValuesProjection>()).forEach(entity -> {
entityList.add(new ExtendedDataPasser<String, Integer, String>(entity.getYear(), entity.getValue(), entity.getType().toString()));
});
return entityList;
}
遺憾的是,這會導致以下錯誤:
org.springframework.beans.NotReadablePropertyException: Invalid property 'year' of bean class [java.util.ArrayList]: Could not find field for property during fallback access!
at org.springframework.data.util.DirectFieldAccessFallbackBeanWrapper.getPropertyValue(DirectFieldAccessFallbackBeanWrapper.java:58) ~[spring-data-commons-2.1.3.RELEASE.jar!/:2.1.3.RELEASE]
at org.springframework.data.projection.PropertyAccessingMethodInterceptor.invoke(PropertyAccessingMethodInterceptor.java:73) ~[spring-data-commons-2.1.3.RELEASE.jar!/:2.1.3.RELEASE]
at org.springframework.data.projection.ProjectingMethodInterceptor.invoke(ProjectingMethodInterceptor.java:64) ~[spring-data-commons-2.1.3.RELEASE.jar!/:2.1.3.RELEASE]
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186) ~[spring-aop-5.1.3.RELEASE.jar!/:5.1.3.RELEASE]
at org.springframework.data.projection.ProxyProjectionFactory$TargetAwareMethodInterceptor.invoke(ProxyProjectionFactory.java:245) ~[spring-data-commons-2.1.3.RELEASE.jar!/:2.1.3.RELEASE]
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186) ~[spring-aop-5.1.3.RELEASE.jar!/:5.1.3.RELEASE]
at org.springframework.data.projection.DefaultMethodInvokingMethodInterceptor.invoke(DefaultMethodInvokingMethodInterceptor.java:59) ~[spring-data-commons-2.1.3.RELEASE.jar!/:2.1.3.RELEASE]
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186) ~[spring-aop-5.1.3.RELEASE.jar!/:5.1.3.RELEASE]
at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:212) ~[spring-aop-5.1.3.RELEASE.jar!/:5.1.3.RELEASE]
at com.sun.proxy.$Proxy133.getYear(Unknown Source) ~[na:na]
也許錯誤的完整屏幕截圖有助於:
當我嘗試訪問year
-attribute時,這是一個例外,這是錯誤:(幾乎相同,只是year
而不是hourValue
)
我是否因為從投影到實體的映射而弄亂了什么?
試試這段代碼,
@Query(value = "Select year, sum(hourvalue) as value, state as type from ITEMHOURS h where item_id = :item_id group by h.year, h.state", nativeQuery = true)
public Optional<Collection<TotalValuesProjection>> getYearTotalsForStateByItem(@Param("item_id") int item_id);
如果有任何問題通知!!
這不是一個可靠的解決方案,而只是大聲思考。 它主要取決於DBMS和Hibernate版本,但在某些情況下,由於大小寫緊急情況可能會發生此類異常,因此請嘗試在本機查詢中添加別名,並將表別名添加到列名稱中,如下所示:
@Query(value = "Select h.year as \"year\", sum(h.hourValue) as \"value\", h.state as \"type\" from ITEMHOURS h where h.item_id = :item_id group by h.year, h.state", nativeQuery = true)
public Optional<Collection<TotalValuesProjection>> getYearTotalsForStateByItem(@Param("item_id") int item_id);
UPD根據Java約定更改hourValue
屬性 - 'h'必須為大寫
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.