Question

My implemented methods are not getting called from DAO Class.

I created bundle xml with name search_dao_bundle.xml as below and placed on same location i.e. tridion_home/config where my cd_storage_xml is placed.

<?xml version="1.0" encoding="UTF-8"?>
<StorageDAOBundles>
<StorageDAOBundle type="persistence">
    <StorageDAO typeMapping="PublishAction" class="com.tridion.storage.extension.search.JPAPublishActionDAO" />
</StorageDAOBundle>
</StorageDAOBundles>

After that I added my bundle entries into my cd_storage_conf.xml as below:

<StorageBindings>
    <Bundle src="search_dao_bundle.xml"/>
</StorageBindings>

and down under I created my new storage type as below:

<Storage Type="persistence" Id="searchdb" dialect="MSSQL" Class="com.tridion.storage.persistence.JPADAOFactory">
    <Pool Type="jdbc" Size="5" MonitorInterval="60" IdleTimeout="120" CheckoutTimeout="120" />
    <DataSource Class="com.microsoft.sqlserver.jdbc.SQLServerDataSource">
        <Property Name="serverName" Value="********" />
        <!--Property Name="portNumber" Value="1433" /-->
        <Property Name="databaseName" Value="********" />
        <Property Name="user" Value="********" />
        <Property Name="password" Value="********" />
    </DataSource>
</Storage>

After that for itemmapping I did below

<ItemTypes defaultStorageId="defaultdb" cached="false"> 
    <Item typeMapping="PublishAction" cached="false" storageId="searchdb" />
</ItemTypes>

I restarted my deployer service got below exception in my core logs

Below is my sample DAO class taken from Mihai Code:

package com.tridion.storage.extension.search;

import java.util.HashMap;
import java.util.Map;
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;
import com.tridion.broker.StorageException;
import com.tridion.storage.extension.search.PublishActionDAO;
import com.tridion.storage.persistence.JPABaseDAO;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

@Component("JPAPublishActionDAO")
@Scope("prototype")
public class JPAPublishActionDAO extends JPABaseDAO implements PublishActionDAO
{
    private static Logger log = LoggerFactory.getLogger(JPAPublishActionDAO.class);
    public JPAPublishActionDAO(String storageId, EntityManagerFactory entityManagerFactory, String storageName) 
    {
        super(storageId, entityManagerFactory, storageName);        
        log.debug("Constructor of JPAPublishActionDAO- storageId:"+storageId);
        log.debug("Constructor of JPAPublishActionDAO- entityManagerFactory:"+entityManagerFactory.isOpen());       
        log.debug("Constructor of JPAPublishActionDAO- storageName:"+storageName);
    }

     public JPAPublishActionDAO(String storageId, EntityManagerFactory entityManagerFactory, EntityManager entityManager, String storageName) 
     {       
            super(storageId, entityManagerFactory, entityManager, storageName);         
     }

     public PublishAction store(PublishAction publishAction) throws StorageException 
     {
         log.debug("JPAPublishActionDAO store");
         //System.out.println("\n******************** From Store *************************************");
            PublishAction entity = (PublishAction) super.create(publishAction);
            return entity;
     }

     @SuppressWarnings("unchecked")
    public PublishAction findByPrimaryKey(long publishActionId) throws StorageException 
     {
            log.debug("JPAPublishActionDAO findByPrimaryKey");
            StringBuilder queryBuilder = new StringBuilder();
            queryBuilder.append("select c from PublishAction c where c.id = :id");

            @SuppressWarnings("rawtypes")
            Map queryParams = new HashMap();
            queryParams.put("id", Long.valueOf(publishActionId));
            log.debug("JPAPublishActionDAO findByPrimaryKey -> queryBuilder- " +queryBuilder.toString());
            return (PublishAction) super.executeQuerySingleResult(queryBuilder.toString(), queryParams);
     }

     @SuppressWarnings("unused")
    public PublishAction update(PublishAction publishAction) throws StorageException 
     {
            log.debug("JPAPublishActionDAO update");
            PublishAction existingPublishAction = findByPrimaryKey(publishAction.getId());

            log.debug("JPAPublishActionDAO update -> existingPublishAction- " +existingPublishAction.toString());
            if (existingPublishAction != null) 
            {
                   return (PublishAction) super.update(publishAction);
            } 
            else 
            {
                   throw new StorageException("Could not find publish action in storage to update!!!");
            }
     }

     public void remove(long publishActionId) throws StorageException 
     {
            log.debug("JPAPublishActionDAO remove");
            PublishAction foundPublishAction = findByPrimaryKey(publishActionId);
            log.debug("JPAPublishActionDAO remove -> foundPublishAction- " +foundPublishAction.toString());
            if (foundPublishAction != null) 
            {
                   super.remove(foundPublishAction);
            }
     }
}

I am able to see that my constructor is getting called i.e. I am getting these logs in my core file logs

log.debug("Constructor of JPAPublishActionDAO- storageId:"+storageId);
log.debug("Constructor of JPAPublishActionDAO- entityManagerFactory:"+entityManagerFactory.isOpen());       
log.debug("Constructor of JPAPublishActionDAO- storageName:"+storageName);

However I am not getting any logs written in other methods like in method public PublishAction store log.debug("JPAPublishActionDAO store");

log.debug("JPAPublishActionDAO findByPrimaryKey");

log.debug("JPAPublishActionDAO update");

What could be the reason, I have entity class with name (PublishAction.java) and Interface class (PublishActionDAO.java) same as in sample code given.

Was it helpful?

Solution

I cannot post formatted code in a comment, hence this new answer.

@sea_gull is right - you need indeed to call the new DAO. The reason for it being this is a new type, so the Content Delivery storage mechanism won't know what to do with it. You have to call it somehow (potentially from a deployer module, but not necessarily). I used a unit test for calling it (just to provie that it works).

This is my sample unit test code I use to call the storage extension with:

package com.tridion.extension.search.test;

import static org.junit.Assert.fail;

import java.util.Date;

import org.junit.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.tridion.broker.StorageException;
import com.tridion.storage.StorageManagerFactory;
import com.tridion.storage.extension.search.PublishAction;
import com.tridion.storage.extension.search.PublishActionDAO;

/**
 * @author Mihai Cadariu
 */
public class DAOTestCase {

    private final Logger log = LoggerFactory.getLogger(DAOTestCase.class);

    /**
     * Test method for
     * {@link com.tridion.storage.extension.search.PublishActionDAO#store(com.tridion.storage.search.PublishAction)}.
     */
    @Test
    public void testDAO() {
        try {
            log.debug("Get PublishActionDAO");
            PublishActionDAO publishActionDAO = (PublishActionDAO) StorageManagerFactory.getDefaultDAO("PublishAction");

            log.debug("Create new PublishAction bean");
            PublishAction publishAction = new PublishAction();
            publishAction.setAction("testStore action");
            publishAction.setContent("testStore content");
            publishAction.setTcmUri("testStore tcmUri");
            publishAction.setUrl("testStore url");
            publishAction.setCreationDate(new Date());

            // Store
            log.debug("Store bean");
            publishAction = publishActionDAO.store(publishAction);
            log.debug("Stored bean " + publishAction);
            long id = publishAction.getId();

            // FindByPrimaryKey
            log.debug("Find PublishAction by PK=" + id);
            publishAction = publishActionDAO.findByPrimaryKey(id);
            log.debug("Found bean " + publishAction);

            if (publishAction == null) {
                log.error("Cannot find bean");
                fail("TestFindByPrimaryKey failed: cannot retrieve object with pk " + id);
            }

            log.debug("Modifying bean content");
            String content = publishAction.getContent();
            content += "\r\nMODIFIED " + new Date();
            publishAction.setContent(content);

            // Update
            log.debug("Update bean");
            publishActionDAO.update(publishAction);

            // Remove
            log.debug("Remove bean");
            publishActionDAO.remove(id);
        } catch (StorageException se) {
            log.debug("TestDAO failed: Exception occurred " + se);
            fail("TestDAO failed: Exception occurred " + se);
            se.printStackTrace();
        }
    }
}

If you call the code from a Deployer extension, this is the sample code I used:

public class PageDeployModule extends PageDeploy {

    private final Logger log = LoggerFactory.getLogger(PageDeployModule.class);

    public PageDeployModule(Configuration config, Processor processor) throws ConfigurationException {
        super(config, processor);
    }

    /**
     * Process the page to be published
     */
    @Override
    protected void processPage(Page page, File pageFile) throws ProcessingException {
        log.debug("Called processPage");

        super.processPage(page, pageFile);
        processItem(page);
    }

    private void processItem(Page page) {
        log.debug("Called processItem");
        try {
            SearchConfiguration config = SearchConfiguration.getInstance();
            String externalUrl = config.getExternalAccessUrl() + page.getURLPath();
            String internalUrl = config.getInternalAccessUrl() + page.getURLPath();

            PublishAction publishAction = new PublishAction();
            publishAction.setAction("Publish");
            publishAction.setTcmUri(page.getId().toString());
            publishAction.setUrl(externalUrl);
            publishAction.setContent(Utils.getPageContent(internalUrl));

            PublishActionDAO publishActionDAO = (PublishActionDAO) StorageManagerFactory.getDefaultDAO("PublishAction");
            publishAction = publishActionDAO.store(publishAction);
            log.debug("Stored bean " + publishAction);
        } catch (StorageException se) {
            log.error("Exception occurred " + se);
        }
    }
}

You can use the same approach for the PageUndeploy, where you mark the action as "Unpublish".

OTHER TIPS

The PublishAction type is not one of the default Tridion types which means it's not going to be used by default. In order for your DAO to be used you need to call it from somehow during the deployment process, usually from a Deployer Module. Can you check how and where are you using this PublishActionDAO?

More information needed: 1) What actually you are publishing while wanted to get invoked these methods - A Dynamic CP or a Page

2) From where you have received this code? I did not see any "create" method in your code...from where did you receive this code

In your previous post related to the "No named Bean loaded" error; Nuno has mentioned for one discussion on Tridion Forum (also given the forum link over there) started by Pankaj Gaur (i.e. me)...did you referred that?

Please note, If your Constructor is getting called, then there is no issue in your configuration at least; it is either the code or the mismatch in the type that you are publishing.

Also Note that, if you are trying to re-publish something without making any change, the Storage Extension might not get loaded (or the methods might not get invoked); so my suggestion during debuging, publsh always after making some changes in your presentation.

I hope it helps, else share the skeleton code along with the JAR file, and I will try t

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top