Muhammad Saleh
Muhammad Saleh

Reputation: 29

getBaseModelDocument(PORTLET_ID,object) returning null document in liferay

Here is my doGetDocument method to get a document but it is returning null doc because getBaseModelDocument(PORTLET_ID,object) returning null. I am using this mehtod in Indexer class of liferay 7.4 because I am indexing my DB data into embedded elasticsearch of liferay.

protected Document doGetDocument(EntityName object) throws Exception {
    Document document = null;
    try {
         document = getBaseModelDocument(getPortletId(),object);

    }catch (Exception e)
    {
        logger.error(e);
    }

    return document;
}

logs :

java.lang.NullPointerException: null at com.liferay.portal.search.internal.spi.model.index.contributor.StagingDocumentContributor.contribute(StagingDocumentContributor.java:52) ~[?:?] at com.liferay.portal.kernel.search.BaseIndexer.getBaseModelDocument(BaseIndexer.java:1257) ~[portal-kernel.jar:?] at com.liferay.portal.kernel.search.BaseIndexer.getBaseModelDocument(BaseIndexer.java:1196)

Upvotes: 0

Views: 123

Answers (1)

jorgediaz-lr
jorgediaz-lr

Reputation: 982

You are having a NullPointerException because there is no Indexer registered with your entity className.

The error is produced here: https://github.com/liferay/liferay-portal/blob/dbbe64ce1855b32057dd49556ee78a051317bcf6/modules/apps/portal-search/portal-search/src/main/java/com/liferay/portal/search/internal/spi/model/index/contributor/StagingDocumentContributor.java#L50-L54

    String className = document.get(Field.ENTRY_CLASS_NAME);

    if (Validator.isNull(className)) {
        return;
    }

    Indexer<?> indexer = indexerRegistry.getIndexer(className);

    if (!indexer.isStagingAware()) {
        return;
    }

So indexerRegistry.getIndexer(className) returns null, causing a NPE in the indexer.isStagingAware() line.

The className value that is get from the document is populated here: https://github.com/liferay/liferay-portal/blob/dbbe64ce1855b32057dd49556ee78a051317bcf6/portal-kernel/src/com/liferay/portal/kernel/search/BaseIndexer.java#L1205-L1222

    String className = baseModel.getModelClassName();

    long classPK = 0;
    long resourcePrimKey = 0;

    if (baseModel instanceof ResourcedModel) {
        ResourcedModel resourcedModel = (ResourcedModel)baseModel;

        classPK = resourcedModel.getResourcePrimKey();
        resourcePrimKey = resourcedModel.getResourcePrimKey();
    }
    else {
        classPK = (Long)baseModel.getPrimaryKeyObj();
    }

    DocumentHelper documentHelper = new DocumentHelper(document);

    documentHelper.setEntryKey(className, classPK);

So you have to double check that the getClassName() method in your custom Indexer returns the same value than the object.getModelClassName() of your entity.

You should have a custom method in your indexer:

@Override
public String getClassName() {
    return ...the className of your entity...;
}

This is necessary because that indexer.getClassName() is used to add the indexer to the registry: https://github.com/liferay/liferay-portal/blob/dbbe64ce1855b32057dd49556ee78a051317bcf6/modules/apps/portal-search/portal-search/src/main/java/com/liferay/portal/search/internal/IndexerRegistryImpl.java#L110

public void register(Indexer<?> indexer) {
    Class<?> clazz = indexer.getClass();

    _indexers.put(clazz.getName(), indexer);

    _indexers.put(indexer.getClassName(), indexer);

Upvotes: 1

Related Questions