如何使用XML覆盖实体的元数据以添加其他gridVisibleFields?

时间:2019-10-29 14:38:02

标签: broadleaf-commerce

我正在使用blc.version 5.1.5-GA。

向产品组添加目标产品时,列表网格仅显示defaultSku.name。我想向listgrid添加其他信息。

这是相关的实体定义:

@OneToMany(targetEntity = ProductProductGroupXrefImpl.class, mappedBy = "productGroup",
    cascade = {CascadeType.MERGE, CascadeType.PERSIST, CascadeType.REFRESH})
@Cache(usage = CacheConcurrencyStrategy.READ_WRITE, region="blProducts")
@BatchSize(size = 50)
@AdminPresentationAdornedTargetCollection(friendlyName = "ProductGroup_Products", 
    group = GroupName.Details, order = 3000,
    joinEntityClass = "com.broadleafcommerce.merchandisinggroup.domain.ProductProductGroupXrefImpl",
    targetObjectProperty = "product",
    parentObjectProperty = "productGroup",
    gridVisibleFields = {"defaultSku.name"})
protected List<ProductProductGroupXref> productXrefs = new ArrayList<>();

有些事情我没有成功尝试过,每个<mo:field>块都是我尝试过的另一件事:

<mo:overrideItem ceilingEntity="org.broadleafcommerce.core.catalog.domain.ProductGroupImpl">
    <mo:field name="defaultSku.ean, defaultSku.name">
        <mo:gridVisibleField value="productXrefs"/>
    </mo:field>

    <mo:field name="productXrefs">
        <mo:gridVisibleField value="defaultSku.name, defaultSku.ean"/>
    </mo:field>

    <mo:field name="defaultSku.ean">
        <mo:gridVisibleField value="productXrefs"/>
    </mo:field>

    <mo:field name="productXrefs">
        <mo:gridVisibleField value="defaultSku.ean"/>
    </mo:field>
</mo:overrideItem>

我每次都要重新启动tomcat服务器,以确保所做的更改已被实际加载。有什么我可以调试和检查的方法来确认吗?

有人提出了类似的问题,他始终无法使XML替代工作。这个问题也需要一个答案:How to override the @AdminPresentation for existing attributes.

2 个答案:

答案 0 :(得分:3)

我相信正确的格式应该是:

<mo:overrideItem ceilingEntity="com.broadleafcommerce.merchandisinggroup.domain.ProductGroup">
    <mo:field name="productXrefs">
        <mo:gridVisibleField value="defaultSku.name"/>
        <mo:gridVisibleField value="defaultSku.ean"/>
    </mo:field>
</mo:overrideItem>

请注意,ceilingEntity是产品组的接口,而不是Impl。

答案 1 :(得分:2)

KeeperofDusk的回答从技术上回答了原始问题,因此我接受了,但是listgrid仍然没有显示其他gridVisibleFields事实证明,我在ceilingEntity属性中使用了错误的软件包名称。

在我的blc版本中,ProductGroup的软件包位于com.broadleafcommerce.merchandisinggroup.domain中,而不是org.broadleafcommerce.core.catalog.domain中。

我调试到AbstractFieldMetadataProvider#getTargetedOverride中。

protected Map<String, MetadataOverride> getTargetedOverride(DynamicEntityDao dynamicEntityDao, String configurationKey, String ceilingEntityFullyQualifiedClassname) {
        if (metadataOverrides != null && (configurationKey != null || ceilingEntityFullyQualifiedClassname != null)) {
            if (metadataOverrides.containsKey(configurationKey)) {
                return metadataOverrides.get(configurationKey);
            }
            if (metadataOverrides.containsKey(ceilingEntityFullyQualifiedClassname)) {
                return metadataOverrides.get(ceilingEntityFullyQualifiedClassname);
            }
            Class<?> test;
            try {
                test = Class.forName(ceilingEntityFullyQualifiedClassname);
            } catch (ClassNotFoundException e) {
                throw new RuntimeException(e);
            }
            if (test.isInterface()) {
                //if it's an interface, get the least derive polymorphic concrete implementation
                Class<?>[] types = dynamicEntityDao.getAllPolymorphicEntitiesFromCeiling(test);
                return metadataOverrides.get(types[types.length-1].getName());
            } else {
                //if it's a concrete implementation, try the interfaces
                Class<?>[] types = test.getInterfaces();
                for (Class<?> type : types) {
                    if (metadataOverrides.containsKey(type.getName())) {
                        return metadataOverrides.get(type.getName());
                    }
                }
            }
        }
        return null;
    }

在这一行上:return metadataOverrides.get(types[types.length-1].getName());我总是空着。正确的行为是该行应返回该字段及其FieldMetadataOverride的LinkedHashMap。

types[types.length-1].getName()应该解析为目标上限实体的完全限定的类名。我尝试在我的IDE中手动评估该行,但一直为空。到目前为止,我还没有意识到传入了错误的完全合格的类名。

然后,我尝试在AdminBasicEntityController中调试到控制器端点。

@RequestMapping(value = "/{id}/{collectionField:.*}/add", method = RequestMethod.GET)
    public String showAddCollectionItem(HttpServletRequest request, HttpServletResponse response, Model model,
            @PathVariable Map<String, String> pathVars,
            @PathVariable(value = "id") String id,
            @PathVariable(value = "collectionField") String collectionField,
            @RequestParam MultiValueMap<String, String> requestParams) throws Exception {
        String sectionKey = getSectionKey(pathVars);
        String mainClassName = getClassNameForSection(sectionKey);
        List<SectionCrumb> sectionCrumbs = getSectionCrumbs(request, sectionKey, id);
        ClassMetadata mainMetadata = service.getClassMetadata(getSectionPersistencePackageRequest(mainClassName,
                sectionCrumbs, pathVars)).getDynamicResultSet().getClassMetaData();
        Property collectionProperty = mainMetadata.getPMap().get(collectionField);
        FieldMetadata md = collectionProperty.getMetadata();

事实证明,BLC_ADMIN_SECTION将节密钥与完全合格的类名相关联,该类名用于解析实体的元数据。我以为问题是在ceiling_entity列中输入了错误的完全合格的类名,因此我将其更改为org.broadleafcommerce.core.catalog.domain.ProductGroup,但这并不能解决问题。这也没有任何意义,因为在这种情况下,我认为关于ProductGroup的任何信息都不会在该管理页面中呈现。

最后,我去检查是否存在完全合格的类名,那是我意识到我进行了十个小时的野鹅追捕。

为将来的Google员工吸取的教训是使用自动完成功能。