PropertyAccessException Ошибка доступа к полю при отражении для постоянного свойства - PullRequest
2 голосов
/ 08 апреля 2020

У меня есть две сущности WorkHolidayEntity и WorkHolidaySegmentEntity. Я использую составной ключ, используя EmbeddedId в этих лицах. WorkHolidaySegmentEntity

package com.example.demo.model;

import org.hibernate.annotations.Type;

import javax.persistence.*;
import javax.validation.constraints.NotNull;
import java.io.Serializable;
import java.math.BigDecimal;
import java.time.LocalDate;
import java.time.LocalDateTime;


@Entity
@Table(name = "WORK_PROCESSED_SEGMENT")
@NamedQuery(name = "WorkHolidaySegmentEntity.findAll", query = "SELECT w FROM WorkHolidaySegmentEntity w")

public class WorkHolidaySegmentEntity extends Model {

    /**
     *
     */
    private static final long serialVersionUID = -5149257772387077483L;

    @EmbeddedId
    private GenericPrimaryKey id;



    @OneToOne(fetch= FetchType.EAGER)
    @JoinColumns({
        @JoinColumn(name="WORK_ITEM_ID", referencedColumnName="WORK_ITEM_ID", insertable = false, updatable = false)
    })
    private WorkHolidayEntity workHolidayEntity ;

    @Column(name="WORK_ITEM_ID")
    @NotNull
    private Long workItemId;

    @Column(name="PAYCODE_ID")
    private Long paycodeId;

    @Column(name="DURATION_IN_DAYS")
    private BigDecimal durationInDays;

    @Column(name="DURATION_IN_SECONDS")
    private Long durationInSeconds;

    @Column(name="START_DATE_TIME")
    //@Type(type = "org.jadira.usertype.dateandtime.threeten.PersistentLocalDateTime")
    @NotNull
    private LocalDateTime startDateTime;

    @Column(name="MONEY_AMOUNT")
    private BigDecimal moneyAmount;

    public LocalDateTime getStartDateTime() {
        return workHolidayEntity.getApplyDate().atStartOfDay();
    }

    @Override
    public boolean isNew() {
        return false;
    }

    public GenericPrimaryKey getId() {
        return id;
    }


    public void setId(GenericPrimaryKey id) {
        this.id = id;
    }


    public Long getWorkItemId() {
        return workItemId;
    }

    public void setWorkItemId(Long workItemId) {
        this.workItemId = workItemId;
    }

    public BigDecimal getDurationInDays() {
        return durationInDays;
    }

    public void setDurationInDays(BigDecimal durationInDays) {
        this.durationInDays = durationInDays;
    }

    public Long getDurationInSeconds() {
        return durationInSeconds;
    }

    public void setDurationInSeconds(Long durationInSeconds) {
        this.durationInSeconds = durationInSeconds;
    }

    public BigDecimal getMoneyAmount() {
        return moneyAmount;
    }

    public void setMoneyAmount(BigDecimal moneyAmount) {
        this.moneyAmount = moneyAmount;
    }

    public Long getPaycodeId() {
        return paycodeId;
    }


    public void setPaycodeId(Long paycodeId) {
        this.paycodeId = paycodeId;
    }

    public Long getHolidayId() {
        return workHolidayEntity.getHolidayId() ;
    }

    public Long getLaborAccountId() {
        return workHolidayEntity.getLaborAccountId() ;
    }

    public Long getOrgJobId() {
        return workHolidayEntity.getOrgJobId() ;
    }
    public Long getTimeEntitySegmentTypeId() {
        return workHolidayEntity.getTimeEntitySegmentTypeId() ;
    }

    public LocalDate getApplyDate() {
        return workHolidayEntity.getApplyDate();
    }


}

workHolidayEntity

package com.example.demo.model;

import org.hibernate.annotations.Type;

import javax.persistence.*;
import javax.validation.constraints.NotNull;
import java.io.Serializable;
import java.time.LocalDate;


@Entity
@Table(name="WORK_HOLIDAY")
@NamedQuery(name="WorkHolidayEntity.findAll", query="SELECT e FROM WorkHolidayEntity e")

public class WorkHolidayEntity extends Model{

    private static final long serialVersionUID = -3259133892721228837L;

    @EmbeddedId
    private GenericPrimaryKey id;


    @Column(name="WORK_ITEM_ID")
    @NotNull
    private Long workItemId;

    @Column(name="HOLIDAY_ID")
    private Long holidayId ;

    @Column(name="LABOR_ACCOUNT_ID")
    private Long laborAccountId ;

    @Column(name="ORGJOB_ID")
    private Long orgJobId ;

    @Column(name="TIME_ENTITY_SEGMENT_TYPE_ID")
    private Long timeEntitySegmentTypeId ;

    @Column(name="APPLY_DATE")
   // @Type(type = "org.jadira.usertype.dateandtime.threeten.PersistentLocalDate")
    @NotNull
    private LocalDate applyDate ;

    @Override
    public GenericPrimaryKey getId() {
        return this.id;
    }

    @Override
    public boolean isNew() {
        return false;
    }

    public Long getWorkItemId() {
        return workItemId;
    }

    public void setWorkItemId(Long workItemId) {
        this.workItemId = workItemId;
    }

    public Long getHolidayId() {
        return holidayId;
    }

    public void setHolidayId(Long holidayId) {
        this.holidayId = holidayId;
    }

    public Long getLaborAccountId() {
        return laborAccountId;
    }

    public void setLaborAccountId(Long laborAccountId) {
        this.laborAccountId = laborAccountId;
    }

    public Long getOrgJobId() {
        return orgJobId;
    }

    public void setOrgJobId(Long orgJobId) {
        this.orgJobId = orgJobId;
    }

    public Long getTimeEntitySegmentTypeId() {
        return timeEntitySegmentTypeId;
    }

    public void setTimeEntitySegmentTypeId(Long timeEntitySegmentTypeId) {
        this.timeEntitySegmentTypeId = timeEntitySegmentTypeId;
    }

    public void setId(GenericPrimaryKey id) {
        this.id = id;
    }

    public LocalDate getApplyDate() {
        return applyDate;
    }

    public void setApplyDate(LocalDate applyDate) {
        this.applyDate = applyDate;
    }


}

Оба объекта Entity расширяют абстрактный класс Model

Model

public abstract class Model implements Persistable, Serializable {
    public Model() {
    }

    public boolean equals(Object obj) {
        if (null == obj) {
            return false;
        } else if (this == obj) {
            return true;
        } else if (!this.getClass().equals(obj.getClass())) {
            return false;
        } else {
            Model that = (Model)obj;
            return null == this.getId() ? false : this.getId().equals(that.getId());
        }
    }

    public int hashCode() {
        int hashCode = 17;
        hashCode = hashCode + (null == this.getId() ? 0 : this.getId().hashCode() * 31);
        return hashCode;
    }
}

Класс Embedabble равен

package com.example.demo.model;

import java.io.Serializable;
import java.math.BigInteger;
import javax.persistence.Column;
import javax.persistence.Embeddable;
import javax.validation.constraints.NotNull;

@Embeddable
public class GenericPrimaryKey implements Serializable {
    private static final long serialVersionUID = -666538159041179819L;
    @Column(
            name = "ID"
    )
    @NotNull
    private Long id;

    public GenericPrimaryKey() {
    }

    public GenericPrimaryKey(Long id) {
        this.id = id;
    }

    public Long getId() {
        return this.id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public boolean equals(Object other) {
        if (this == other) {
            return true;
        } else if (!(other instanceof GenericPrimaryKey)) {
            return false;
        } else {
            GenericPrimaryKey castOther = (GenericPrimaryKey)other;
            return this.id.equals(castOther.id);
        }
    }

    @Override
    public int hashCode() {
    final int prime = 31;
    int hash = 17;
    hash = hash * prime + this.id.intValue();

    return hash;
}
}

Мой класс RepositoryImpl имеет нижеприведенную реализацию

public List<WorkHolidaySegmentEntity> findWorkHolidayByWorkItemIds(List<Long> workItemIdList) {
        if (workItemIdList == null || workItemIdList.isEmpty())
            return new ArrayList<>() ;
           Session session = entityManager.unwrap(Session.class);
            Query query = session.createQuery("select whs FROM WorkHolidaySegmentEntity whs " +
                     "inner join fetch whs.workHolidayEntity wh " +
                    " where whs.workItemId IN (:workItemIdList)") ;

            query.setParameterList("workItemIdList", workItemIdList);

            List<WorkHolidaySegmentEntity> workHolidays = query.list();
            return workHolidays;
    }

, когда я запускаю код, я получаю propertyAccessException

PropertyAccessException Error accessing field [private java.lang.Long com.example.demo.model.GenericPrimaryKey.id] by reflection for persistent property [com.example.demo.model.GenericPrimaryKey#id] : com.example.demo.model.WorkHolidayEntity@11"

Не уверен, почему он нам недоступен поле id.

Все работает нормально, если я использую Long вместо EmbeddedId, т.е. заменяя @EmbeddedId на частный идентификатор GenericPrimaryKey; с @ID private Long id;

Может кто-нибудь сообщить мне, почему я получаю ошибку при использовании EmbeddedId.

Стек ошибок:

Exception in thread "main" javax.persistence.PersistenceException: org.hibernate.property.access.spi.PropertyAccessException: Error accessing field [private java.lang.Long com.example.demo.model.GenericPrimaryKey.id] by reflection for persistent property [com.example.demo.model.GenericPrimaryKey#id] : com.example.demo.model.WorkHolidayEntity@11
    at org.hibernate.internal.ExceptionConverterImpl.convert(ExceptionConverterImpl.java:154)
    at org.hibernate.query.internal.AbstractProducedQuery.list(AbstractProducedQuery.java:1535)
    at com.example.demo.repository.WorkHolidayJpaRepositoryImpl.findWorkHolidayByWorkItemIds(WorkHolidayJpaRepositoryImpl.java:33)
    at com.example.demo.repository.WorkHolidayJpaRepositoryImpl$$FastClassBySpringCGLIB$$4c260788.invoke(<generated>)
    at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:218)
    at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.invokeJoinpoint(CglibAopProxy.java:769)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:163)
    at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:747)
    at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:366)
    at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:99)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
    at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:747)
    at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:689)
    at com.example.demo.repository.WorkHolidayJpaRepositoryImpl$$EnhancerBySpringCGLIB$$c7a03c65.findWorkHolidayByWorkItemIds(<generated>)
    at com.example.demo.DemoApplication.main(DemoApplication.java:25)
Caused by: org.hibernate.property.access.spi.PropertyAccessException: Error accessing field [private java.lang.Long com.example.demo.model.GenericPrimaryKey.id] by reflection for persistent property [com.example.demo.model.GenericPrimaryKey#id] : com.example.demo.model.WorkHolidayEntity@11
    at org.hibernate.property.access.spi.GetterFieldImpl.get(GetterFieldImpl.java:75)
    at org.hibernate.tuple.component.AbstractComponentTuplizer.getPropertyValue(AbstractComponentTuplizer.java:59)
    at org.hibernate.type.ComponentType.getPropertyValue(ComponentType.java:419)
    at org.hibernate.type.ComponentType.getHashCode(ComponentType.java:246)
    at org.hibernate.engine.spi.EntityUniqueKey.generateHashCode(EntityUniqueKey.java:67)
    at org.hibernate.engine.spi.EntityUniqueKey.<init>(EntityUniqueKey.java:48)
    at org.hibernate.type.ManyToOneType.resolve(ManyToOneType.java:252)
    at org.hibernate.engine.internal.TwoPhaseLoad.doInitializeEntity(TwoPhaseLoad.java:226)
    at org.hibernate.engine.internal.TwoPhaseLoad.initializeEntity(TwoPhaseLoad.java:160)
    at org.hibernate.loader.Loader.initializeEntitiesAndCollections(Loader.java:1179)
    at org.hibernate.loader.Loader.processResultSet(Loader.java:1028)
    at org.hibernate.loader.Loader.doQuery(Loader.java:964)
    at org.hibernate.loader.Loader.doQueryAndInitializeNonLazyCollections(Loader.java:354)
    at org.hibernate.loader.Loader.doList(Loader.java:2815)
    at org.hibernate.loader.Loader.doList(Loader.java:2797)
    at org.hibernate.loader.Loader.listIgnoreQueryCache(Loader.java:2629)
    at org.hibernate.loader.Loader.list(Loader.java:2624)
    at org.hibernate.loader.hql.QueryLoader.list(QueryLoader.java:506)
    at org.hibernate.hql.internal.ast.QueryTranslatorImpl.list(QueryTranslatorImpl.java:396)
    at org.hibernate.engine.query.spi.HQLQueryPlan.performList(HQLQueryPlan.java:219)
    at org.hibernate.internal.SessionImpl.list(SessionImpl.java:1396)
    at org.hibernate.query.internal.AbstractProducedQuery.doList(AbstractProducedQuery.java:1558)
    at org.hibernate.query.internal.AbstractProducedQuery.list(AbstractProducedQuery.java:1526)
    ... 13 more
Caused by: java.lang.IllegalArgumentException: Can not set java.lang.Long field com.example.demo.model.GenericPrimaryKey.id to com.example.demo.model.WorkHolidayEntity
    at sun.reflect.UnsafeFieldAccessorImpl.throwSetIllegalArgumentException(UnsafeFieldAccessorImpl.java:167)
    at sun.reflect.UnsafeFieldAccessorImpl.throwSetIllegalArgumentException(UnsafeFieldAccessorImpl.java:171)
    at sun.reflect.UnsafeFieldAccessorImpl.ensureObj(UnsafeFieldAccessorImpl.java:58)
    at sun.reflect.UnsafeObjectFieldAccessorImpl.get(UnsafeObjectFieldAccessorImpl.java:36)
    at java.lang.reflect.Field.get(Field.java:393)
    at org.hibernate.property.access.spi.GetterFieldImpl.get(GetterFieldImpl.java:71)
    ... 35 more
...