Во-первых: я использую Spring-Boot Data JPA
с Java 8.
В моей базе данных есть таблица, в которой моя сущность определяется следующим образом:
@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]
Может быть, поможет полный скриншот ошибки:
![enter image description here](https://i.stack.imgur.com/vfkDB.png)
Это исключение, когда я пытаюсь получить доступ к year
-атрибуту в первую очередь, это ошибка: (почти такая же, просто year
вместо hourValue
)
![enter image description here](https://i.stack.imgur.com/HtKD3.png)
Я что-то связал с отображением проекции на сущность?