У меня есть две сущности 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