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 CategoryAttributeListener
do 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!
albudarov
(Alexander Budarov)
March 5, 2020, 8:46am
#2
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$CategoryAttribute
in postman with the body like this
({{baseUrl}}
env is http://localhost:8080/app/rest/v2
for 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.
gorbunkov
(Maxim Gorbunkov)
March 6, 2020, 12:06pm
#5
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 !