blaze-persistence icon indicating copy to clipboard operation
blaze-persistence copied to clipboard

ArrayIndexOutOfBounds when saving OneToMany relation and using annotation processor

Open bryhemm opened this issue 11 months ago • 2 comments
trafficstars

I've run into an exception when saving an Entity View that contains a OneToMany mapping. The exception only occurs when I'm using the blaze-persistence-entity-view-processor-jakarta annotation processor. If I don't use the annotation processor, everything behaves as expected.

My Entities are:

@Entity
@Data
@NoArgsConstructor
public class Workflow {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column
    private Long id;

    @OneToMany(mappedBy = "workflow")
    private List<WorkflowStep> steps;
}
@Entity
@Data
@NoArgsConstructor
public class WorkflowStep {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column
    private Long id;
    
    @ManyToOne
    @JoinColumn(name="workflow_id")
    private Workflow workflow;
}

And my views are:

@EntityView(Workflow.class)
public interface WorkflowIdView {
        @IdMapping
        Long getId();
}
@EntityView(Workflow.class)
@CreatableEntityView
@UpdatableEntityView
public interface WorkflowView extends WorkflowIdView {
    @UpdatableMapping
    @MappingInverse(removeStrategy = InverseRemoveStrategy.REMOVE)
    List<WorkflowStepView> getSteps()
}
@EntityView(WorkflowStep.class)
@CreatableEntityView
@UpdatableEntityView
public interface WorkflowStepView {
    @IdMapping
    Long getId();

    @UpdatableMapping(cascade = CascadeType.PERSIST)
    WorkflowIdView getWorkflow();
    void setWorkflow(WorkflowIdView workflow);
}

To test this, I'm saving the WorkflowView and as WorkflowStepView at the same time:

        var step1 = evm.create(WorkflowStepView.class);
        var wf = evm.create(WorkflowView.class);
        wf.getSteps().add(step1);

        evm.save(em, wf);

If I don't add a step to the WorkflowView or if I disable the annotation processor, it saves correctly.

The exception I'm seeing is

java.lang.ArrayIndexOutOfBoundsException: Index 4 out of bounds for length 4
        at com.blazebit.persistence.view.impl.accessor.DirtyStateViewAttributeAccessor.setValue(DirtyStateViewAttributeAccessor.java:81) ~[blaze-persistence-entity-view-impl-jakarta-1.6.14.jar:1.6.14]
        at com.blazebit.persistence.view.impl.mapper.ReferenceViewAttributeMapper.map(ReferenceViewAttributeMapper.java:42) ~[blaze-persistence-entity-view-impl-jakarta-1.6.14.jar:1.6.14]
        at com.blazebit.persistence.view.impl.mapper.CompositeMapper.map(CompositeMapper.java:24) ~[blaze-persistence-entity-view-impl-jakarta-1.6.14.jar:1.6.14]
        at com.blazebit.persistence.view.impl.mapper.TargetViewClassBasedMapper.map(TargetViewClassBasedMapper.java:28) ~[blaze-persistence-entity-view-impl-jakarta-1.6.14.jar:1.6.14]
        at com.blazebit.persistence.view.impl.entity.InverseViewToEntityMapper$1.run(InverseViewToEntityMapper.java:91) ~[blaze-persistence-entity-view-impl-jakarta-1.6.14.jar:1.6.14]
        at com.blazebit.persistence.view.impl.update.flush.CompositeAttributeFlusher.flushEntity(CompositeAttributeFlusher.java:645) ~[blaze-persistence-entity-view-impl-jakarta-1.6.14.jar:1.6.14]
        at com.blazebit.persistence.view.impl.entity.InverseViewToEntityMapper.flushEntity(InverseViewToEntityMapper.java:109) ~[blaze-persistence-entity-view-impl-jakarta-1.6.14.jar:1.6.14]
        at com.blazebit.persistence.view.impl.entity.TargetViewClassBasedInverseViewToEntityMapper.flushEntity(TargetViewClassBasedInverseViewToEntityMapper.java:38) ~[blaze-persistence-entity-view-impl-jakarta-1.6.14.jar:1.6.14]
        at com.blazebit.persistence.view.impl.update.flush.InverseFlusher.flushQuerySetEntityOnElement(InverseFlusher.java:464) ~[blaze-persistence-entity-view-impl-jakarta-1.6.14.jar:1.6.14]
        at com.blazebit.persistence.view.impl.update.flush.InverseFlusher.flushQuerySetEntityOnViewElement(InverseFlusher.java:454) ~[blaze-persistence-entity-view-impl-jakarta-1.6.14.jar:1.6.14]
        at com.blazebit.persistence.view.impl.update.flush.InverseFlusher.flushQuerySetEntityOnElement(InverseFlusher.java:447) ~[blaze-persistence-entity-view-impl-jakarta-1.6.14.jar:1.6.14]
        at com.blazebit.persistence.view.impl.update.flush.CollectionAttributeFlusher$ElementFlusherQueryExecutor.onAddedAndUpdatedInverseElement(CollectionAttributeFlusher.java:1763) ~[blaze-persistence-entity-view-impl-jakarta-1.6.14.jar:1.6.14]
        at com.blazebit.persistence.view.impl.update.flush.CollectionAttributeFlusher.visitInverseElementFlushersForActions(CollectionAttributeFlusher.java:1813) ~[blaze-persistence-entity-view-impl-jakarta-1.6.14.jar:1.6.14]
        at com.blazebit.persistence.view.impl.update.flush.CollectionAttributeFlusher.flushEntity(CollectionAttributeFlusher.java:725) ~[blaze-persistence-entity-view-impl-jakarta-1.6.14.jar:1.6.14]
        at com.blazebit.persistence.view.impl.update.flush.CollectionAttributeFlusher.flushEntity(CollectionAttributeFlusher.java:53) ~[blaze-persistence-entity-view-impl-jakarta-1.6.14.jar:1.6.14]
        at com.blazebit.persistence.view.impl.update.flush.CompositeAttributeFlusher.deferredFlushEntity(CompositeAttributeFlusher.java:857) ~[blaze-persistence-entity-view-impl-jakarta-1.6.14.jar:1.6.14]       
        at com.blazebit.persistence.view.impl.update.flush.CompositeAttributeFlusher.flushEntity(CompositeAttributeFlusher.java:762) ~[blaze-persistence-entity-view-impl-jakarta-1.6.14.jar:1.6.14]
        at com.blazebit.persistence.view.impl.update.EntityViewUpdaterImpl.executePersist(EntityViewUpdaterImpl.java:721) ~[blaze-persistence-entity-view-impl-jakarta-1.6.14.jar:1.6.14]
        at com.blazebit.persistence.view.impl.update.EntityViewUpdaterImpl.executePersist(EntityViewUpdaterImpl.java:716) ~[blaze-persistence-entity-view-impl-jakarta-1.6.14.jar:1.6.14]
        at com.blazebit.persistence.view.impl.EntityViewManagerImpl.update(EntityViewManagerImpl.java:1180) ~[blaze-persistence-entity-view-impl-jakarta-1.6.14.jar:1.6.14]
        at com.blazebit.persistence.view.impl.EntityViewManagerImpl.update(EntityViewManagerImpl.java:1142) ~[blaze-persistence-entity-view-impl-jakarta-1.6.14.jar:1.6.14]
        at com.blazebit.persistence.view.impl.EntityViewManagerImpl.save(EntityViewManagerImpl.java:1059) ~[blaze-persistence-entity-view-impl-jakarta-1.6.14.jar:1.6.14]
        at com.example.demo.WorkflowController.test(WorkflowController.java:32) ~[main/:na]

bryhemm avatar Dec 05 '24 18:12 bryhemm

Can you please share this example/demo application? That would make it easier to look into.

beikov avatar Dec 06 '24 16:12 beikov

Here is an example project https://github.com/bryhemm/spring-blaze

bryhemm avatar Dec 06 '24 22:12 bryhemm