rdbmsStore issue during committing CommitContext (CUBA 6.7.2)

There is such method: AttributeSecuritySupport#afterMerge, which has parameter, that supposed to be detached, for recursive traversing attributes.
But that method called from RdbmsStore.java:383 with managed entity, thats why we have OutOfMemoryError

4 Likes

Hi Rushan,

Could you provide the sample project?

Thanks,
Andrey Subbotin

Сould you tell, please, is it okey to traverse all loaded attributes of MANAGED entity every time when you commit it? I think that it is very dangerous and heavy operation, and there are should be some restrictions on which attributes to traverse.
We trying to save entity which have relations with almost all other data. Because on merge your platform traverse all attributes of this entity the big part of database is merges too.

Rushan,

MetadataTools should traverse only loaded attributes of the entity. It checks that attribute is loaded. See com.haulmont.cuba.core.global.MetadataTools#internalTraverseAttributes and persistentAttributesLoadChecker.isLoaded.

I’ll answer about traversing all attributes of the entity after some tests.

Thanks,
Andrey

I have checked traversing attributes with unit-test. Referenced non-loaded objects are not traversed.
Sample test:

@Entity(name = "ref$Driver")
@Table(name = "REF_DRIVER")
@NamePattern("%s|name")
public class Driver extends StandardEntity {

    private static final long serialVersionUID = -3978805138573255022L;

    @OneToOne(fetch = FetchType.LAZY)
    @OnDeleteInverse(DeletePolicy.DENY)
    @JoinColumn(name = "CALLSIGN_ID")
    protected DriverCallsign callsign;

    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "PLATFORM_ENTITY_ID")
    protected SamplePlatformEntity platformEntity;
}

@Test    
public void testTraverse() {
    Driver d = dataManager.load(LoadContext.create(Driver.class)
            .setId(driver.getId()).setView(View.LOCAL));
    Transaction tx = cont.persistence().createTransaction();
    try {
        Driver m = cont.persistence().getEntityManager().merge(d);
        metadata.getTools().traverseAttributes(m, (entity, property) -> {
            if (!(entity instanceof Driver)) {
                fail(String.format("Traverse not-loaded entities: %s", entity.getClass()));
            }
        });
    } finally {
        tx.end();
    }
}

Could you provide sample project for your case?

Thanks,
Andrey

My apologies, it was my mistake.
I have overridden GlobalPersistentAttributesLoadChecker bean globally (even for core level), but I forget about CorePersistentAttributesLoadChecker.
Beacuse of this, isLoaded always returned true for merged entity…
Additionally, JavaDocs of AttributeSecuritySupport#afterMerge method really confused me:
they say: "@param entity detached entity"
I thought that parameter is supposed to be always detached, but it was just incorrect JavaDocs…
Sorry for taking your time