2017-04-06 29 views
1

我們使用Hibernate Envers從特定日期的實體及其相關實體獲取完整數據。問題在於,在訪問集合中的項目時發生錯誤,該集合在該時刻之後被刪除。 所以看來問題是因爲訪問數據庫來檢索不存在的實體。Envers:錯誤映射具有已刪除實體的集合

這是主要的實體:

@XmlType 
    @XmlRootElement 
    @Entity 
    @Audited 
    @Table(name = PayrollEntity.TABLE_NAME) 
    @NamedQueries({ 
    @NamedQuery(name = PayrollEntity.EXISTS_BY_ID_QUERY_NAME, query = PayrollEntity.EXISTS_BY_ID_QUERY, hints = {@QueryHint(name = "org.hibernate.cacheable", value = "true")}), 
    @NamedQuery(name = PayrollEntity.FIND_PAYROLL_QUERY_NAME, query = PayrollEntity.FIND_PAYROLL_QUERY, hints = {@QueryHint(name = "org.hibernate.cacheable", value = "true")}), 
    @NamedQuery(name = PayrollEntity.FIND_EXTRAPAY_QUERY_NAME, query = PayrollEntity.FIND_EXTRAPAY_QUERY, hints = {@QueryHint(name = "org.hibernate.cacheable", value = "true")}), 
    @NamedQuery(name = PayrollEntity.FIND_PAYROLLS_BY_EMPLOYMENT_QUERY_NAME, query = PayrollEntity.FIND_PAYROLLS_BY_EMPLOYMENT_QUERY, hints = {@QueryHint(name = "org.hibernate.cacheable", value = "true")}), 
    }) 
    public class PayrollEntity extends AbstractEntity { 

    private static final long serialVersionUID = -1982937254314630067L; 

    /* PARAMS */ 
    public static final String EXISTS_PAYROLL_EXCLUDEDIDPAYROLL_PARAM = "idPayroll"; 
    public static final String EXISTS_PAYROLL_IDPAYROLLTYPE_PARAM = "idPayrollType"; 
    public static final String EXISTS_PAYROLL_IDEMPLOYMENT_PARAM = "idEmployment"; 
    public static final String EXISTS_PAYROLL_YEAR_PARAM = "year"; 
    public static final String EXISTS_PAYROLL_MONTH_PARAM = "month"; 
    public static final String EXISTS_PAYROLL_IDEXTRAPAY_PARAM = "idExtraPay"; 

    /* QUERIES */ 
    public static final String EXISTS_BY_ID_QUERY_NAME = "EXISTS_PAYROLL_BY_ID"; 
    public static final String EXISTS_BY_ID_QUERY = 
    "SELECT e.idPayroll FROM PayrollEntity e WHERE e.idPayroll = :" + EXISTS_BY_ID_QUERY_PARAM; 

    public static final String FIND_PAYROLL_QUERY_NAME = "EXISTS_PAYROLL_BY_CONCEPTUAL_ID"; 
    public static final String FIND_PAYROLL_QUERY = 
    "SELECT e FROM PayrollEntity e WHERE e.idPayroll != :" + EXISTS_PAYROLL_EXCLUDEDIDPAYROLL_PARAM 
    + " AND e.employment.idEmployment = :" + EXISTS_PAYROLL_IDEMPLOYMENT_PARAM 
    + " AND e.year = :" + EXISTS_PAYROLL_YEAR_PARAM 
    + " AND e.month = :" + EXISTS_PAYROLL_MONTH_PARAM 
    + " AND e.payrollType.idPayrollType = :" + EXISTS_PAYROLL_IDPAYROLLTYPE_PARAM; 

    public static final String FIND_EXTRAPAY_QUERY_NAME = "EXISTS_EXTRAPAY_BY_CONCEPTUAL_ID"; 
    public static final String FIND_EXTRAPAY_QUERY = 
    "SELECT e FROM PayrollEntity e WHERE e.idPayroll != :" + EXISTS_PAYROLL_EXCLUDEDIDPAYROLL_PARAM 
    + " AND e.employment.idEmployment = :" + EXISTS_PAYROLL_IDEMPLOYMENT_PARAM 
    + " AND e.year = :" + EXISTS_PAYROLL_YEAR_PARAM 
    + " AND e.month = :" + EXISTS_PAYROLL_MONTH_PARAM 
    + " AND e.payrollType.idPayrollType = :" + EXISTS_PAYROLL_IDPAYROLLTYPE_PARAM 
    + " AND e.extraPay.idExtraPay = :" + EXISTS_PAYROLL_IDEXTRAPAY_PARAM; 

    public static final String FIND_PAYROLLS_BY_EMPLOYMENT_QUERY_NAME = "FIND_PAYROLLS_BY_EMPLOYMENT"; 
    public static final String FIND_PAYROLLS_BY_EMPLOYMENT_QUERY = 
    "SELECT e FROM PayrollEntity e WHERE e.employment.idEmployment = :" + EXISTS_PAYROLL_IDEMPLOYMENT_PARAM 
    + " AND e.year = :" + EXISTS_PAYROLL_YEAR_PARAM 
    + " AND e.month = :" + EXISTS_PAYROLL_MONTH_PARAM; 

    /* TABLE */ 
    public static final String TABLE_NAME = "EP_PAYROLL"; 

    /* COLUMNS */ 
    public static final String ID_PAYROLL_COLUMN = "ID_PAYROLL"; 
    public static final String VERSION_COLUMN = "VERSION"; 
    public static final String ID_EMPLOYMENT_COLUMN = "ID_EMPLOYMENT"; 
    public static final String ID_PAYROLL_TYPE_COLUMN = "ID_PAYROLL_TYPE"; 
    public static final String YEAR_COLUMN = "YEAR"; 
    public static final String MONTH_COLUMN = "MONTH"; 
    public static final String CALCULATION_DATETIME_COLUMN = "CALCULATION_DATETIME"; 
    public static final String PAYSLIP_GENERATION_DATETIME_COLUMN = "PAYSLIP_GENERATION_DATETIME"; 
    public static final String ID_EXTRA_PAY_COLUMN = "ID_EXTRA_PAY"; 
    public static final String DISCOUNT_RATE_CALCULATED = "DISCOUNT_RATE_CALCULATED"; 
    public static final String DISCOUNT_RATE_SOLICITED = "DISCOUNT_RATE_SOLICITED"; 
    public static final String DISCOUNT_RATE_APPLIED = "DISCOUNT_RATE_APPLIED"; 

    private String idPayroll; 
    private int version; 
    private PayrollTypeEntity payrollType; 
    private EmploymentEntity employment; 
    private int year; 
    private int month; 
    private DateTime calculationDateTime; 
    private DateTime payslipGenerationDatetime; 
    private List<PayrollSalaryItemEntity> payrollSalaryItems; 
    private ExtraPayEntity extraPay; 
    private Float discountRateCalculated; 
    private Float discountRateSolicited; 
    private Float discountRateApplied; 

    @Column(name = CALCULATION_DATETIME_COLUMN) 
    @Type(type = JODA_DATE_TIME_JPA_CONVERTER) 
    public DateTime getCalculationDateTime() { 
    return calculationDateTime; 
    } 

    @Column(name = DISCOUNT_RATE_APPLIED, columnDefinition = "decimal(4,2)") 
    public Float getDiscountRateApplied() { 
    return discountRateApplied; 
    } 

    @Column(name = DISCOUNT_RATE_CALCULATED, columnDefinition = "decimal(4,2)") 
    public Float getDiscountRateCalculated() { 
    return discountRateCalculated; 
    } 

    @Column(name = DISCOUNT_RATE_SOLICITED, columnDefinition = "decimal(4,2)") 
    public Float getDiscountRateSolicited() { 
    return discountRateSolicited; 
    } 

    @ManyToOne(targetEntity = EmploymentEntity.class) 
    @JoinColumn(name = ID_EMPLOYMENT_COLUMN, referencedColumnName = EmploymentEntity.ID_EMPLOYMENT_COLUMN) 
    public EmploymentEntity getEmployment() { 
    return employment; 
    } 

    @ManyToOne(targetEntity = ExtraPayEntity.class) 
    @JoinColumn(name = ID_EXTRA_PAY_COLUMN, referencedColumnName = ExtraPayEntity.ID_EXTRA_PAY_COLUMN) 
    public ExtraPayEntity getExtraPay() { 
    return extraPay; 
    } 

    @Column(name = ID_PAYROLL_COLUMN, nullable = false, updatable = false, length = 36) 
    @Id 
    @GeneratedValue(generator = UUID_GENERATOR_NAME) 
    @GenericGenerator(name = UUID_GENERATOR_NAME, strategy = UUID_GENERATOR_STRATEGY) 
    public String getIdPayroll() { 
    return idPayroll; 
    } 

    @Column(name = MONTH_COLUMN) 
    public int getMonth() { 
    return month; 
    } 

    @OneToMany(mappedBy = "payroll", cascade = CascadeType.ALL, orphanRemoval = true) 
    public List<PayrollSalaryItemEntity> getPayrollSalaryItems() { 
    return payrollSalaryItems; 
    } 

    @Audited(targetAuditMode = RelationTargetAuditMode.NOT_AUDITED) 
    @ManyToOne(targetEntity = PayrollTypeEntity.class) 
    @JoinColumn(name = ID_PAYROLL_TYPE_COLUMN, referencedColumnName = PayrollTypeEntity.ID_PAYROLL_TYPE_COLUMN) 
    public PayrollTypeEntity getPayrollType() { 
    return payrollType; 
    } 

    @Column(name = PAYSLIP_GENERATION_DATETIME_COLUMN) 
    @Type(type = JODA_DATE_TIME_JPA_CONVERTER) 
    public DateTime getPayslipGenerationDatetime() { 
    return payslipGenerationDatetime; 
    } 

    @Version 
    public int getVersion() { 
    return version; 
    } 

    @Column(name = YEAR_COLUMN) 
    public int getYear() { 
    return year; 
    } 

    public void setCalculationDateTime(DateTime calculationDate) { 
    this.calculationDateTime = calculationDate; 
    } 

    public void setDiscountRateApplied(Float discountRateApplied) { 
    this.discountRateApplied = discountRateApplied; 
    } 

    public void setDiscountRateCalculated(Float discountRateCalculated) { 
    this.discountRateCalculated = discountRateCalculated; 
    } 

    public void setDiscountRateSolicited(Float discountRateSolicited) { 
    this.discountRateSolicited = discountRateSolicited; 
    } 

    public void setEmployment(EmploymentEntity employment) { 
    this.employment = employment; 
    } 

    public void setExtraPay(ExtraPayEntity extraPay) { 
    this.extraPay = extraPay; 
    } 

    public void setIdPayroll(String idPayroll) { 
    this.idPayroll = idPayroll; 
    } 

    public void setMonth(int month) { 
    this.month = month; 
    } 

    public void setPayrollSalaryItems(List<PayrollSalaryItemEntity> payrollSalaryItems) { 
    this.payrollSalaryItems = payrollSalaryItems; 
    } 

    public void setPayrollType(PayrollTypeEntity payrollType) { 
    this.payrollType = payrollType; 
    } 

    public void setPayslipGenerationDatetime(DateTime payslipGenerationDatetime) { 
    this.payslipGenerationDatetime = payslipGenerationDatetime; 
    } 

    public void setVersion(int version) { 
    this.version = version; 
    } 

    public void setYear(int year) { 
    this.year = year; 
    } 
    } 

這是我們用來從envers獲取數據的代碼:

public PayrollEntity findHistorical(String idPayroll, DateTime date) { 
AuditReader reader = AuditReaderFactory.get(getEntityManager()); 
return reader.find(PayrollEntity.class, idPayroll, (int) 
    reader.createQuery() 
    .forRevisionsOfEntity(PayrollEntity.class, false, true) 
    .add(AuditEntity.revisionProperty("revTimestamp").lt(date.getMillis())) 
    .addProjection(AuditEntity.revisionNumber().max()) 
    .add(AuditEntity.id().eq(idPayroll)) 
    .getSingleResult()); 
    } 

然後,我們嘗試用推土機將數據的DTO映射,我們得到這個錯誤:

Caused by: javax.persistence.EntityNotFoundException: Unable to find es.gc.epsilon.core.domain.SalaryItemEntity with id 15 
at org.hibernate.ejb.Ejb3Configuration$Ejb3EntityNotFoundDelegate.handleEntityNotFound(Ejb3Configuration.java:157) [hibernate-entitymanager-4.2.14.SP1-redhat-1.jar:4.2.14.SP1-redhat-1] 
at org.hibernate.proxy.AbstractLazyInitializer.checkTargetState(AbstractLazyInitializer.java:262) [hibernate-core-4.2.14.SP1-redhat-1.jar:4.2.14.SP1-redhat-1] 
at org.hibernate.proxy.AbstractLazyInitializer.initialize(AbstractLazyInitializer.java:176) [hibernate-core-4.2.14.SP1-redhat-1.jar:4.2.14.SP1-redhat-1] 
at org.hibernate.proxy.AbstractLazyInitializer.getImplementation(AbstractLazyInitializer.java:286) [hibernate-core-4.2.14.SP1-redhat-1.jar:4.2.14.SP1-redhat-1] 
at org.hibernate.proxy.pojo.javassist.JavassistLazyInitializer.invoke(JavassistLazyInitializer.java:185) [hibernate-core-4.2.14.SP1-redhat-1.jar:4.2.14.SP1-redhat-1] 

正如我所說,這似乎是因爲推土機訪問從payro刪除的項目llSalaryItems集合來自主實體的列表。

所以,問題是。有可能將實體中的數據映射到集合中的已刪除項目到DTO中?我們正在做正確的方式嗎?

PD:我們正在使用Hibernate的版本4.2.21.Final

在此先感謝。

回答

0

您所描述的是由HHH-8093HHH-8051標識的問題,這兩個問題都暫定爲Hibernate Envers 6.0版本。

如果我在6.0版本之前找到這些,我會嘗試。

很明顯,這並不能解決您對Hibernate Envers 4.2的迫切需求,而這種需求很古老,不再維護或修補。

+0

謝謝你的回答@naros,我以爲是這個錯誤https://hibernate.atlassian.net/browse/HHH-5845它已經修復了4.2.21.Final版本。 有什麼解決方法可以嘗試,直到您發佈解決方案? – jeyViso