Is it possable to overwrite system CategoryAttributeListener or could someone help me with this BUG :( please!

Hi,
I found there may be a BUG or something wrong when i write CategoryAttribute into the entity through REST-API Addon.

the CategoryAttribute.category attribute referencing a Category entity, and CategoryAttributeListenerdo a thing as this before upsert:

    protected void setCategoryEntityType(CategoryAttribute entity) {
        if (entity.getCategory() != null) {
            entity.setCategoryEntityType(entity.getCategory().getEntityType());
        }
    }

however the entity.getCategory()entity is fetch by com.haulmont.cuba.core.app.importexport.EntityImportExport#findReferenceEntity in this method:

            LoadContext<? extends Entity> ctx = LoadContext.create(entity.getClass())
                    .setSoftDeletion(false)
                    .setView(new View(entity.getMetaClass().getJavaClass(), false))
                    .setId(entity.getId());
            result = dataManager.load(ctx);

this result only contain uuid and version of the Referenced Category Entity.

as a result , the entity.getCategory()entity didn’t contain the attribute entityType, so entity.getCategory().getEntityType() get a exception as this :

15:53:16.721 ERROR c.h.cuba.core.sys.ServiceInterceptor    - Exception: 
java.lang.IllegalStateException: Cannot get unfetched attribute [entityType] from detached object com.haulmont.cuba.core.entity.Category-2348f01b-79d9-8034-1de3-01305c564adb [detached].
	at ...
        at ...

Therefore I think the quickest way to fix this bug may be to fix this method setCategoryEntityType()
like this:


    protected void setCategoryEntityType(CategoryAttribute entity) {
        if (entity.getCategory() != null&&entity.getCategoryEntityType()==null) {
            entity.setCategoryEntityType(entity.getCategory().getEntityType());
        }
    }

Is There somebody can help please?
Thanks!

Hi,
Thank you for bug report.

To help CUBA team to quickly fix the problem, can you please provide:

  • CUBA platform version, REST API addon version
  • sample project where exception can be reproduced
  • sample REST request and response

Hi Alex, Thanks for your quick reply.
the version info is :

    ext.cubaVersion = '7.1.4'
    appComponent('com.haulmont.addon.restapi:restapi-global:7.1.1')

it is easy to reproduced
there are some sample step

S1. add a Category in the GUI.DynamicAttribute,
S2. go to database, and findout the Category.ID for me it is :2348f01b-79d9-8034-1de3-01305c564adb
S3.request POST {{baseUrl}}/entities/sys$CategoryAttributein postman with the body like this
({{baseUrl}} env is http://localhost:8080/app/rest/v2for me)

{
    
    "localeNames": "#\n#Tue Mar 03 15:35:28 CST 2020\n",
    "code": "dada2test2",
    "categoryEntityType": "sale_Customer",
    "required": false,
    "targetScreens": "",
    "defaultEntity": {
        "stringEntityId": null,
        "intEntityId": null,
        "entityId": null,
        "longEntityId": null
    },
    "lookup": false,
    "orderNo": 1,
    "dataType": "BOOLEAN",
    "defaultBoolean": true,
    "localeDescriptions": "#\n#Tue Mar 03 15:35:28 CST 2020\n",
    "name": "da2test2",
    "category": {
        "id": "2348f01b-79d9-8034-1de3-01305c564adb",
        "entityType": "sale_Customer"
     }
     
}

I doubt that is there some way to overwrite system entity listener, for it is a emergency problem for me to fix this error temporarily.
Thanks.

Hi,

The com.haulmont.cuba.core.app.dynamicattributes.CategoryAttributeListener listener is a Spring bean, you can easily replace it with your own bean.

Create a listener for CategoryAttribute entity, e.g.:

public class MyCategoryAttributeListener implements BeforeInsertEntityListener<CategoryAttribute>,
        BeforeUpdateEntityListener<CategoryAttribute> {

    @Override
    public void onBeforeInsert(CategoryAttribute entity, EntityManager entityManager) {
        setCategoryEntityType(entity);
    }

    @Override
    public void onBeforeUpdate(CategoryAttribute entity, EntityManager entityManager) {
        setCategoryEntityType(entity);
    }

    protected void setCategoryEntityType(CategoryAttribute entity) {
        if (entity.getCategory() != null && entity.getCategoryEntityType() == null) {
            entity.setCategoryEntityType(entity.getCategory().getEntityType());
        }
    }
}

and register this bean in the spring.xml:

<bean id="report_CategoryAttributeListener" class="com.company.sample.core.MyCategoryAttributeListener"/>

After that your listener will replace the one provided by the platform.

thank you very much, Max !