tridiontridion-2011tridion-content-deliverytridion-storage-extension

Implemented Method in DAO Class is not getting called in storage extension of Tridion 2011 SP1


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.


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".