4 Replies Latest reply on Apr 18, 2017 12:01 PM by jviso

    Error when loading collection with deleted entities

    jviso

      Hi everyone,

       

      We are trying to get the full data from an entity and its related entities in a certain date. And the problem is that we get an error when accessing items from a collection that were deleted after that moment.
      So it seems the problem is because is accessing to DB to retrieve entities that doesn't exist anymore.

       

      This is the main entity:

      @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;
        }
      
      }
      

      This is the code we use to get the data from 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());
      }
      

       

      Then we try to map the data to a DTO using dozer, and we get this error:

       

      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]
      

       

      As I said, it seems it's because dozer access to a deleted item from the payrollSalaryItems collection List<PayrollSalaryItemEntity> from the main entity.

       

      So, the question is. It's possible to map data from an entity containint deleted items in a collection to a DTO? Are we doing on the right way?

       

      PD: we are using the Hibernate version 4.2.21.Final

       

      Thanks in advance.

        • 1. Re: Error when loading collection with deleted entities
          andey

          >>>javax.persistence.EntityNotFoundException: Unable to find es.gc.epsilon.core.domain.SalaryItemEntity with id 15

           

          Where is your "SalaryItemEntity" Entity class? Have you defined it ? How did you define relationship with the entity "SalaryItemEntity"?

          • 2. Re: Error when loading collection with deleted entities
            jviso

            Hi andey,

             

             

            PayrollEntity contains a list of PayrollSalaryItemEntity:

             

            @XmlType
            @XmlRootElement
            @Entity
            @Audited
            @Table(name = PayrollSalaryItemEntity.TABLE_NAME)
            @Inheritance(strategy = InheritanceType.JOINED)
            @NamedQueries({
              @NamedQuery(name = PayrollSalaryItemEntity.EXISTS_BY_ID_QUERY_NAME, query = PayrollSalaryItemEntity.EXISTS_BY_ID_QUERY, hints = {@QueryHint(name = "org.hibernate.cacheable", value = "true")}),
              @NamedQuery(name = PayrollSalaryItemEntity.FIND_SALARYITEM_IN_PAYROLL_QUERY_NAME, query = PayrollSalaryItemEntity.FIND_SALARYITEM_IN_PAYROLL_QUERY, hints = {@QueryHint(name = "org.hibernate.cacheable", value = "true")}),
              @NamedQuery(name = PayrollSalaryItemEntity.FIND_SALARYITEM_BY_PRICE_SOURCE_QUERY_NAME, query = PayrollSalaryItemEntity.FIND_SALARYITEM_BY_PRICE_SOURCE_QUERY, hints = {@QueryHint(name = "org.hibernate.cacheable", value = "true")})
            })
            public class PayrollSalaryItemEntity extends AbstractWithRevisionEntity {
              private static final long serialVersionUID = 5385511119811347696L;
            
              /* PARAMS */
              public static final String FIND_SALARYITEM_IN_PAYROLL_EXCLUDEDIDPAYROLLSALARYITEM_PARAM = "idPayrollSalaryItem";
              public static final String FIND_SALARYITEM_IN_PAYROLL_SALARYITEM_PARAM = "idSalaryItem";
              public static final String FIND_SALARYITEM_IN_PAYROLL_IDPAYROLL_PARAM = "idPayroll";
              public static final String FIND_SALARYITEM_PRICE_SOURCE_IDPAYROLL_PARAM = "idPayroll";
              public static final String FIND_SALARYITEM_PRICE_SOURCE_IDSALARYITEM_PARAM = "idSalaryItem";
              public static final String FIND_SALARYITEM_PRICE_SOURCE_TYPE_PARAM = "priceSourceType";
              public static final String FIND_SALARYITEM_PRICE_SOURCE_ENTITY_ID_TYPE_PARAM = "priceSourceEntityId";
            
              /* QUERIES */
              public static final String EXISTS_BY_ID_QUERY_NAME = "EXISTS_PAYROLLSALARYITEM_BY_ID";
              public static final String EXISTS_BY_ID_QUERY =
              "SELECT e.idPayrollSalaryItem FROM PayrollSalaryItemEntity e WHERE e.idPayrollSalaryItem = :" + EXISTS_BY_ID_QUERY_PARAM;
            
              public static final String FIND_SALARYITEM_IN_PAYROLL_QUERY_NAME = "FIND_SALARYITEM_IN_PAYROLL";
              public static final String FIND_SALARYITEM_IN_PAYROLL_QUERY =
              "SELECT e FROM PayrollSalaryItemEntity e WHERE e.idPayrollSalaryItem != :" + FIND_SALARYITEM_IN_PAYROLL_EXCLUDEDIDPAYROLLSALARYITEM_PARAM
              + " AND e.payroll.idPayroll= :" + FIND_SALARYITEM_IN_PAYROLL_IDPAYROLL_PARAM
              + " AND e.salaryItem.idSalaryItem = :" + FIND_SALARYITEM_IN_PAYROLL_SALARYITEM_PARAM;
            
              public static final String FIND_SALARYITEM_BY_PRICE_SOURCE_QUERY_NAME = "FIND_SALARYITEM_BY_PRICE_SOURCE";
              public static final String FIND_SALARYITEM_BY_PRICE_SOURCE_QUERY =
              "SELECT e FROM PayrollSalaryItemEntity e WHERE e.payroll.idPayroll= :" + FIND_SALARYITEM_PRICE_SOURCE_IDPAYROLL_PARAM
              + " AND e.salaryItem.idSalaryItem= :" + FIND_SALARYITEM_PRICE_SOURCE_IDSALARYITEM_PARAM
              + " AND e.calcDetail.priceSourceType= :" + FIND_SALARYITEM_PRICE_SOURCE_TYPE_PARAM
              + " AND e.calcDetail.priceSourceEntityId = :" + FIND_SALARYITEM_PRICE_SOURCE_ENTITY_ID_TYPE_PARAM;
            
              /* TABLE */
              public static final String TABLE_NAME = "EP_PAYROLL_SALARY_ITEM";
            
              /* COLUMNS */
              public static final String ID_PAYROLL_SALARY_ITEM_COLUMN = "ID_PAYROLL_SALARY_ITEM";
              public static final String ID_PAYROLL_COLUMN = "ID_PAYROLL";
              public static final String VERSION_COLUMN = "VERSION";
              public static final String ID_SALARY_ITEM_COLUMN = "ID_SALARY_ITEM";
              public static final String UNITS_COLUMN = "UNITS";
              public static final String PRICE_COLUMN = "PRICE";
              public static final String VALUE_COLUMN = "VALUE";
              public static final String FORCED_COLUMN = "FORCED";
            
              private String idPayrollSalaryItem;
              private int version;
              private PayrollEntity payroll;
              private SalaryItemEntity salaryItem;
              private BigDecimal units;
              private BigDecimal price;
              private BigDecimal value;
              private boolean forced;
            
              private List<PayrollProrateItemEntity> payrollProrateItems;
              private PayrollItemDetailEntity calcDetail;
            
              @OneToOne(mappedBy = "payrollSalaryItem", cascade = CascadeType.ALL, orphanRemoval = true)
              public PayrollItemDetailEntity getCalcDetail() {
              return calcDetail;
              }
            
              @Column(name = ID_PAYROLL_SALARY_ITEM_COLUMN, nullable = false, updatable = false, length = 36)
              @Id
              @GeneratedValue(generator = UUID_GENERATOR_NAME)
              @GenericGenerator(name = UUID_GENERATOR_NAME, strategy = UUID_GENERATOR_STRATEGY)
              public String getIdPayrollSalaryItem() {
              return idPayrollSalaryItem;
              }
            
              @ManyToOne
              @JoinColumn(name = ID_PAYROLL_COLUMN, referencedColumnName = PayrollEntity.ID_PAYROLL_COLUMN)
              public PayrollEntity getPayroll() {
              return payroll;
              }
            
              @OneToMany(mappedBy = "payrollSalaryItem", cascade = CascadeType.ALL, orphanRemoval = true)
              public List<PayrollProrateItemEntity> getPayrollProrateItems() {
              return payrollProrateItems;
              }
            
              @Column(name = PRICE_COLUMN, columnDefinition = "decimal(13,4)")
              public BigDecimal getPrice() {
              return price;
              }
            
              @ManyToOne
              @JoinColumn(name = ID_SALARY_ITEM_COLUMN, referencedColumnName = SalaryItemEntity.ID_SALARY_ITEM_COLUMN)
              @NotFound(action = NotFoundAction.IGNORE)
              public SalaryItemEntity getSalaryItem() {
              return salaryItem;
              }
            
              @Column(name = UNITS_COLUMN, columnDefinition = "decimal(13,4)")
              public BigDecimal getUnits() {
              return units;
              }
            
              @Column(name = VALUE_COLUMN, columnDefinition = "decimal(13,4)")
              public BigDecimal getValue() {
              return value;
              }
            
              @Version
              public int getVersion() {
              return version;
              }
            
              @Column(name = FORCED_COLUMN, columnDefinition = "BIT", length = 1)
              @NotNull
              public boolean isForced() {
              return forced;
              }
            
              public void setCalcDetail(PayrollItemDetailEntity calcDetail) {
              this.calcDetail = calcDetail;
              }
            
              public void setForced(boolean forced) {
              this.forced = forced;
              }
            
              public void setIdPayrollSalaryItem(String idPayrollSalaryItem) {
              this.idPayrollSalaryItem = idPayrollSalaryItem;
              }
            
              public void setPayroll(PayrollEntity payroll) {
              this.payroll = payroll;
              }
            
              public void setPayrollProrateItems(List<PayrollProrateItemEntity> payrollProrateItems) {
              this.payrollProrateItems = payrollProrateItems;
              }
            
              public void setPrice(BigDecimal price) {
              this.price = price;
              }
            
              public void setSalaryItem(SalaryItemEntity salaryItem) {
              this.salaryItem = salaryItem;
              }
            
              public void setUnits(BigDecimal units) {
              this.units = units;
              }
            
              public void setValue(BigDecimal value) {
              this.value = value;
              }
            
              public void setVersion(int version) {
              this.version = version;
              }
            }
            

            And PayrollSalaryItemEntity contains a SalaryItemEntity:

             

            @XmlType
            @XmlRootElement
            @Entity
            @Audited
            @Cacheable(true)
            @Table(name = SalaryItemEntity.TABLE_NAME)
            @SecondaryTable(name = SalaryItemEntity.TABLE_SPAIN_NAME, pkJoinColumns = {@PrimaryKeyJoinColumn(name = SalaryItemEntity.ID_SALARY_ITEM_COLUMN)})
            @Inheritance(strategy = InheritanceType.JOINED)
            @NamedQueries({
              @NamedQuery(name = SalaryItemEntity.EXISTS_BY_ID_QUERY_NAME, query = SalaryItemEntity.EXISTS_BY_ID_QUERY, hints = {@QueryHint(name = "org.hibernate.cacheable", value = "true")}),
              @NamedQuery(name = SalaryItemEntity.FIND_BY_CODE_QUERY_NAME, query = SalaryItemEntity.FIND_BY_CODE_QUERY, hints = {@QueryHint(name = "org.hibernate.cacheable", value = "true")}),
              @NamedQuery(name = SalaryItemEntity.MAX_CODE_QUERY_NAME, query = SalaryItemEntity.MAX_CODE_QUERY, hints = {@QueryHint(name = "org.hibernate.cacheable", value = "true")})
            })
            public class SalaryItemEntity extends AbstractLocalizedWithRevisionEntity {
            
              /* TABLE */
              public static final String TABLE_NAME = "EP_SALARY_ITEM";
              public static final String TABLE_SPAIN_NAME = "EP_SPAIN_SALARY_ITEM";
            
              /* PARAMS */
              public static final String ID_SALARY_ITEM_PARAM = "idSalaryItem";
              public static final String CODE_PARAM = "code";
            
              /* QUERIES */
              public static final String MAX_CODE_QUERY_NAME = "MAX_CODE";
              public static final String MAX_CODE_QUERY =
              "SELECT max(si.code) FROM SalaryItemEntity si";
            
              public static final String EXISTS_BY_ID_QUERY_NAME = "EXISTS_SALARYITEM_BY_ID";
              public static final String EXISTS_BY_ID_QUERY =
              "SELECT si.idSalaryItem FROM SalaryItemEntity si WHERE si.idSalaryItem = :" + EXISTS_BY_ID_QUERY_PARAM;
            
              public static final String FIND_BY_CODE_QUERY_NAME = "FIND_BY_CODE";
              public static final String FIND_BY_CODE_QUERY =
              "SELECT si FROM SalaryItemEntity si WHERE si.code = :" + CODE_PARAM;
            
              /* COLUMNS */
              public static final String ID_SALARY_ITEM_COLUMN = "ID_SALARY_ITEM";
              public static final String VERSION_COLUMN = "VERSION";
              public static final String NAME_COLUMN = "NAME";
              public static final String OBSERVATIONS_COLUMN = "OBSERVATIONS";
              public static final String CODE_COLUMN = "CODE";
              public static final String SYSTEM_COLUMN = "SYSTEM";
              public static final String ID_ACCUMULATION_COLUMN = "ID_ACCUMULATION";
              public static final String ID_INCIDENCE_TYPE_COLUMN = "ID_INCIDENCE_TYPE";
              public static final String ID_SALARY_ITEM_INCIDENCE_COLUMN = "ID_SALARY_ITEM_INCIDENCE";
            
              public static final String ID_COTIZACION_COLUMN = "ID_COTIZACION";
              public static final String ID_CRA_COLUMN = "ID_CRA";
              public static final String ID_TRIBUTACION_COLUMN = "ID_TRIBUTACION";
              public static final String ID_PER_GEN_IRPF_COLUMN = "ID_PER_GEN_IRPF";
              public static final String ID_CALCULO_IRPF_COLUMN = "ID_CALCULO_IRPF";
              public static final String ID_CERTIF_IRPF_COLUMN = "ID_CERTIF_IRPF";
              public static final String ID_FACTOR_CANT_COLUMN = "ID_FACTOR_CANT";
              public static final String ID_FACTOR_CALEND_COLUMN = "ID_FACTOR_CALEND";
              public static final String ID_ATRASOS_COLUMN = "ID_ATRASOS";
              public static final String REDUCE_COLUMN = "REDUCE";
              public static final String ES_PAGA_COLUMN = "ES_PAGA";
            
              private String idSalaryItem;
              private int version;
              private String nameDeprecated;
              private String observations;
              private Integer code;
              private boolean system;
              private SalaryItemAccumulationEntity accumulation;
              private IncidenceTypeEntity incidenceType;
              // Spain table
              private SpainTributacionEntity tributacion;
              private SpainAtrasosEntity atrasos;
              private SpainCalculoIrpfEntity calculoIrpf;
              private SpainCertifIrpfEntity certificadoIrpf;
              private SpainCotizacionEntity cotizacion;
              private SpainCraEntity cra;
              private SpainFactorCalendarioEntity factorCalendario;
              private SpainFactorCantidadEntity factorCantidad;
              private SpainPerGenIrpfEntity perGenIrpf;
              private boolean reduce;
              private boolean esPaga;
              private SalaryItemEntity salaryItemIncidence;
              private List<SalaryGroupItemEntity> salaryGroupItems;
              private List<CollectivePriceEntity> collectivesPrices;
              private List<RemunerationStructurePriceEntity> remunerationStrPrices;
              private List<CompanyPayslipSalaryItemEntity> companyPayslipSalaryItems;
              private Map<String, SalaryItemTranEntity> salaryItemTrans;
            
              @Audited(targetAuditMode = RelationTargetAuditMode.NOT_AUDITED)
              @ManyToOne(fetch = FetchType.LAZY)
              @JoinColumn(name = ID_ACCUMULATION_COLUMN, referencedColumnName = SalaryItemAccumulationEntity.ID_SALARY_ITEM_ACCUMULATION_COLUMN)
              public SalaryItemAccumulationEntity getAccumulation() {
              return accumulation;
              }
            
              @Transient
              public List<CollectiveEntity> getAppliedCollectives() {
              List<CollectiveEntity> appliedCollectives = new ArrayList<>();
              if (collectivesPrices != null) {
              appliedCollectives = new ArrayList<>();
              for (CollectivePriceEntity cpe : collectivesPrices) {
              if (!appliedCollectives.contains(cpe.getCollective())) {
              appliedCollectives.add(cpe.getCollective());
              }
              }
              }
              return appliedCollectives;
              }
            
              @Transient
              public List<RemunerationStructureEntity> getAppliedRemunerationStr() {
              List<RemunerationStructureEntity> appliedRemunerationStr = new ArrayList<>();
              if (remunerationStrPrices != null) {
              appliedRemunerationStr = new ArrayList<>();
              for (RemunerationStructurePriceEntity rsp : remunerationStrPrices) {
              if (!appliedRemunerationStr.contains(rsp.getRemunerationStructure())) {
              appliedRemunerationStr.add(rsp.getRemunerationStructure());
              }
              }
              }
              return appliedRemunerationStr;
              }
            
              @Transient
              public List<SalaryGroupEntity> getAppliedSalaryGroups() {
              List<SalaryGroupEntity> appliedSalaryGroups = new ArrayList<>();
              if (salaryGroupItems != null) {
              appliedSalaryGroups = new ArrayList<>();
              for (SalaryGroupItemEntity spi : salaryGroupItems) {
              if (!appliedSalaryGroups.contains(spi.getSalaryGroup())) {
              appliedSalaryGroups.add(spi.getSalaryGroup());
              }
              }
              }
              return appliedSalaryGroups;
              }
            
              @Audited(targetAuditMode = RelationTargetAuditMode.NOT_AUDITED)
              @ManyToOne(fetch = FetchType.LAZY)
              @JoinColumn(table = TABLE_SPAIN_NAME, name = ID_ATRASOS_COLUMN, referencedColumnName = SpainAtrasosEntity.ID_ATRASOS_COLUMN)
              public SpainAtrasosEntity getAtrasos() {
              return atrasos;
              }
            
              @Audited(targetAuditMode = RelationTargetAuditMode.NOT_AUDITED)
              @ManyToOne(fetch = FetchType.LAZY)
              @JoinColumn(table = TABLE_SPAIN_NAME, name = ID_CALCULO_IRPF_COLUMN, referencedColumnName = SpainCalculoIrpfEntity.ID_CALCULO_IRPF_COLUMN)
              public SpainCalculoIrpfEntity getCalculoIrpf() {
              return calculoIrpf;
              }
            
              @Audited(targetAuditMode = RelationTargetAuditMode.NOT_AUDITED)
              @ManyToOne(fetch = FetchType.LAZY)
              @JoinColumn(table = TABLE_SPAIN_NAME, name = ID_CERTIF_IRPF_COLUMN, referencedColumnName = SpainCertifIrpfEntity.ID_CERTIF_IRPF_COLUMN)
              public SpainCertifIrpfEntity getCertificadoIrpf() {
              return certificadoIrpf;
              }
            
              @Column(name = CODE_COLUMN)
              public Integer getCode() {
              return code;
              }
            
              @OneToMany(mappedBy = "salaryItem")
              public List<CollectivePriceEntity> getCollectivesPrices() {
              return collectivesPrices;
              }
            
              @OneToMany(mappedBy = "salaryItem", cascade = CascadeType.ALL, orphanRemoval = true)
              public List<CompanyPayslipSalaryItemEntity> getCompanyPayslipSalaryItems() {
              return companyPayslipSalaryItems;
              }
            
              @Audited(targetAuditMode = RelationTargetAuditMode.NOT_AUDITED)
              @ManyToOne(fetch = FetchType.LAZY)
              @JoinColumn(table = TABLE_SPAIN_NAME, name = ID_COTIZACION_COLUMN, referencedColumnName = SpainCotizacionEntity.ID_COTIZACION_COLUMN)
              public SpainCotizacionEntity getCotizacion() {
              return cotizacion;
              }
            
              @Audited(targetAuditMode = RelationTargetAuditMode.NOT_AUDITED)
              @ManyToOne(fetch = FetchType.LAZY)
              @JoinColumn(table = TABLE_SPAIN_NAME, name = ID_CRA_COLUMN, referencedColumnName = SpainCraEntity.ID_CRA_COLUMN)
              public SpainCraEntity getCra() {
              return cra;
              }
            
              @Audited(targetAuditMode = RelationTargetAuditMode.NOT_AUDITED)
              @ManyToOne(fetch = FetchType.LAZY)
              @JoinColumn(table = TABLE_SPAIN_NAME, name = ID_FACTOR_CALEND_COLUMN, referencedColumnName = SpainFactorCalendarioEntity.ID_FACTOR_CALEND_COLUMN)
              public SpainFactorCalendarioEntity getFactorCalendario() {
              return factorCalendario;
              }
            
              @Audited(targetAuditMode = RelationTargetAuditMode.NOT_AUDITED)
              @ManyToOne(fetch = FetchType.LAZY)
              @JoinColumn(table = TABLE_SPAIN_NAME, name = ID_FACTOR_CANT_COLUMN, referencedColumnName = SpainFactorCantidadEntity.ID_FACTOR_CANT_COLUMN)
              public SpainFactorCantidadEntity getFactorCantidad() {
              return factorCantidad;
              }
            
              @Column(name = ID_SALARY_ITEM_COLUMN, nullable = false, updatable = false, length = 36)
              @Id
              @GeneratedValue(generator = UUID_GENERATOR_NAME)
              @GenericGenerator(name = UUID_GENERATOR_NAME, strategy = UUID_GENERATOR_STRATEGY)
              public String getIdSalaryItem() {
              return idSalaryItem;
              }
            
              @Audited(targetAuditMode = RelationTargetAuditMode.NOT_AUDITED)
              @ManyToOne(fetch = FetchType.LAZY)
              @JoinColumn(name = ID_INCIDENCE_TYPE_COLUMN, referencedColumnName = IncidenceTypeEntity.ID_INCIDENCE_TYPE_COLUMN)
              public IncidenceTypeEntity getIncidenceType() {
              return incidenceType;
              }
            
              @Transient
              public String getName() {
              try {
              return this.getSalaryItemTrans().get(getCurrentLocale()).getName();
              } catch (Exception e) {
              return null;
              }
              }
            
              @Column(name = NAME_COLUMN, length = DEFAULT_MEDIUM_STRING_FIELD_LENGTH)
              public String getNameDeprecated() {
              return nameDeprecated;
              }
            
              @Column(name = OBSERVATIONS_COLUMN, columnDefinition = "text")
              public String getObservations() {
              return observations;
              }
            
              @Audited(targetAuditMode = RelationTargetAuditMode.NOT_AUDITED)
              @ManyToOne(fetch = FetchType.LAZY)
              @JoinColumn(table = TABLE_SPAIN_NAME, name = ID_PER_GEN_IRPF_COLUMN, referencedColumnName = SpainPerGenIrpfEntity.ID_PER_GEN_IRPF_COLUMN)
              public SpainPerGenIrpfEntity getPerGenIrpf() {
              return perGenIrpf;
              }
            
              @OneToMany(mappedBy = "salaryItem")
              public List<RemunerationStructurePriceEntity> getRemunerationStrPrices() {
              return remunerationStrPrices;
              }
            
              @OneToMany(mappedBy = "salaryItem")
              public List<SalaryGroupItemEntity> getSalaryGroupItems() {
              return salaryGroupItems;
              }
            
              @Audited(targetAuditMode = RelationTargetAuditMode.NOT_AUDITED)
              @ManyToOne(fetch = FetchType.LAZY)
              @JoinColumn(name = ID_SALARY_ITEM_INCIDENCE_COLUMN, referencedColumnName = SalaryItemEntity.ID_SALARY_ITEM_COLUMN)
              public SalaryItemEntity getSalaryItemIncidence() {
              return salaryItemIncidence;
              }
            
              @OneToMany(mappedBy = "salaryItem", cascade = CascadeType.ALL, orphanRemoval = true)
              @MapKey(name = "locale")
              public Map<String, SalaryItemTranEntity> getSalaryItemTrans() {
              return salaryItemTrans;
              }
            
              @Audited(targetAuditMode = RelationTargetAuditMode.NOT_AUDITED)
              @ManyToOne(fetch = FetchType.LAZY)
              @JoinColumn(table = TABLE_SPAIN_NAME, name = ID_TRIBUTACION_COLUMN, referencedColumnName = SpainTributacionEntity.ID_TRIBUTACION_COLUMN)
              public SpainTributacionEntity getTributacion() {
              return tributacion;
              }
            
              @Version
              public int getVersion() {
              return version;
              }
            
              @Override
              public int hashCode() {
              return idSalaryItem != null ? idSalaryItem.hashCode() : 0;
              }
            
              @Column(table = TABLE_SPAIN_NAME, name = ES_PAGA_COLUMN, columnDefinition = "BIT", length = 1)
              @NotNull
              public boolean isEsPaga() {
              return esPaga;
              }
            
              @Column(table = TABLE_SPAIN_NAME, name = REDUCE_COLUMN, columnDefinition = "BIT", length = 1)
              @NotNull
              public boolean isReduce() {
              return reduce;
              }
            
              @Column(name = SYSTEM_COLUMN, columnDefinition = "BIT", length = 1)
              @NotNull
              public boolean isSystem() {
              return system;
              }
            
              public void setAccumulation(SalaryItemAccumulationEntity accumulation) {
              this.accumulation = accumulation;
              }
            
              public void setAtrasos(SpainAtrasosEntity atrasos) {
              this.atrasos = atrasos;
              }
            
              public void setCalculoIrpf(SpainCalculoIrpfEntity calculoIrpf) {
              this.calculoIrpf = calculoIrpf;
              }
            
              public void setCertificadoIrpf(SpainCertifIrpfEntity certificadoIrpf) {
              this.certificadoIrpf = certificadoIrpf;
              }
            
              public void setCode(Integer code) {
              this.code = code;
              }
            
              public void setCollectivesPrices(List<CollectivePriceEntity> collectivesPrices) {
              this.collectivesPrices = collectivesPrices;
              }
            
              public void setCompanyPayslipSalaryItems(List<CompanyPayslipSalaryItemEntity> companyPayslipSalaryItems) {
              this.companyPayslipSalaryItems = companyPayslipSalaryItems;
              }
            
              public void setCotizacion(SpainCotizacionEntity cotizacion) {
              this.cotizacion = cotizacion;
              }
            
              public void setCra(SpainCraEntity cra) {
              this.cra = cra;
              }
            
              public void setEsPaga(boolean esPaga) {
              this.esPaga = esPaga;
              }
            
              public void setFactorCalendario(SpainFactorCalendarioEntity factorCalendario) {
              this.factorCalendario = factorCalendario;
              }
            
              public void setFactorCantidad(SpainFactorCantidadEntity factorCantidad) {
              this.factorCantidad = factorCantidad;
              }
            
              public void setIdSalaryItem(String idSalaryItem) {
              this.idSalaryItem = idSalaryItem;
              }
            
              public void setIncidenceType(IncidenceTypeEntity incidenceType) {
              this.incidenceType = incidenceType;
              }
            
              public void setNameDeprecated(String name) {
              this.nameDeprecated = name;
              }
            
              public void setObservations(String observations) {
              this.observations = observations;
              }
            
              public void setPerGenIrpf(SpainPerGenIrpfEntity perGenIrpf) {
              this.perGenIrpf = perGenIrpf;
              }
            
              public void setReduce(boolean reduce) {
              this.reduce = reduce;
              }
            
              public void setRemunerationStrPrices(List<RemunerationStructurePriceEntity> remunerationStrPrices) {
              this.remunerationStrPrices = remunerationStrPrices;
              }
            
              public void setSalaryGroupItems(List<SalaryGroupItemEntity> salaryGroupItems) {
              this.salaryGroupItems = salaryGroupItems;
              }
            
              public void setSalaryItemIncidence(SalaryItemEntity salaryItemIncidence) {
              this.salaryItemIncidence = salaryItemIncidence;
              }
            
              public void setSalaryItemTrans(Map<String, SalaryItemTranEntity> salaryItemTrans) {
              this.salaryItemTrans = salaryItemTrans;
              }
            
              public void setSystem(boolean system) {
              this.system = system;
              }
            
              public void setTributacion(SpainTributacionEntity tributacion) {
              this.tributacion = tributacion;
              }
            
              public void setVersion(int version) {
              this.version = version;
              }
            
            }
            
            • 3. Re: Error when loading collection with deleted entities
              andey

              javax.persistence.EntityNotFoundException: Unable to find es.gc.epsilon.core.domain.SalaryItemEntity with id 15,

               

              It might be triggering lazy loading on the entity. Check your mapping relationship or This probably means that the entity was deleted (perhaps by another thread) at some point after the lazy proxy (reference to it) was created.

               

              • 4. Re: Error when loading collection with deleted entities
                jviso

                andey actually, that's the problem. The SalaryItemEntity with id 15 existed on the date we are querying, so it's in the collection returned by Envers. But we get the error when accessing it. So, as I said before, it seems the problem is because is accessing to DB to retrieve entities that doesn't exist anymore.

                 

                In Hibernate Envers, all related collections of an entity are loaded lazily, regardless of what fetch type is set. So, please, what I have to do to access that entity returned by Envers which is already deleted?