簡體   English   中英

如何從Spring Data JPA NativeQuery接收集合? [導致NotReadablePropertyException]

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM